За год работы с ИИ-агентом на потоке в репозитории ideav/crm накопилось 6258 коммитов, 2310 тикетов и 2583 смерженных пулл-реквеста. Почти всё это написано агентом: задачи ставятся тикетами, приёмка идёт по PR, инструкции живут в CLAUDE.md, база знаний — в docs/kb/, полный цикл разработки приложения — в docs/integram-app-workflow.md. Темп в пару десятков PR в день быстро выжигает иллюзию, что если агент сделал глупость, значит, он глупый. При разборе каждого случая оказывалось, что инструкция допускала сделанное, а иногда прямо к нему вела.
Первый дефект — правило написано в форме «как не надо». В проектах два типа связей между таблицами: ссылка (обычный внешний ключ) и подчинённая таблица (позиции заказа, контакты сотрудника). Перепутать их дорого, схему приходится переделывать. В инструкции стояло предупреждение: «Для ссылки не использовать сокращённую форму dreq/{source} t=<targetTableId> (без предварительного dref). Эта форма не создаёт FK, она создаёт подчинённую таблицу». Предупреждение точное, причина названа, последствия описаны. Агент прошёл по нему и снова сделал справочники подчинёнными таблицами. Реакция заказчика в issue #2897 состояла из одной строки: «Напиши, как надо, чтобы выполнять непосредственно по писанному». Предупреждение говорит, чего не делать, и молчит о том, что делать вместо. Инструкция, которую нельзя исполнить дословно, исполняется приблизительно. Сейчас на этом месте раздел 2.5: четыре теста выбора (переиспользование, жизненный цикл, способ ввода в интерфейсе, направление владения), таблица сравнения, самопроверка по метаданным (ref/ref_id — ссылка, arr_id без ref — подчинённая) и два разных паттерна создания. Ни одного «не делай». Сделали чек-лист, по которому выбор однозначен. Справочники, превратившиеся в подчинённые таблицы, перестали появляться, а переделок схемы «с нуля, потому что связи не того типа» после правки раздела не было.
| Дефект инструкции | Пример | Лечение |
|---|---|---|
| Правило написано в форме «как не надо» | Предупреждение про dreq/{source} t=<targetTableId> | Раздел 2.5: четыре теста выбора, таблица сравнения, самопроверка по метаданным, два паттерна создания |
| У правила нет проверки | Правило про замороженный день вернулось тремя тикетами за четыре дня | Модуль-реестр 05-invariants.js и страж guardPlanOps на границе записи плана |
| Правило написано прозой | Пересказ объяснения для человека в виде предостережения | Отдельный документ с однозначными формулировками и проверками |
Второй дефект — у правила нет проверки. В планировании производства есть замороженный день: когда оператор закрыл смену, автоматика туда не лезет. Правило записано в техническом задании, согласовано с заказчиком, живёт в документе несколько месяцев. За четыре дня оно вернулось тремя тикетами подряд: #4347 «ПРОСРОЧКА!!! НАПИХАЛИ ЗАДАНИЙ В ЗАМОРОЖЕННЫЙ ДЕНЬ!!!», #4434 дефекты кнопок «Упорядочить» и «Сгенерировать», #4436 «Зачем залез в замороженный день что-то менять?». Каждый фикс был честным и каждый закрывал свой путь: правило проверялось в трёх разных местах одной функции, а путей записи плана было больше трёх. Агент читал ТЗ, соглашался, чинил то, на что показали, и следующая кнопка ломала то же самое. Вылечилось это переносом правила в исполняемую форму, не формулировкой. Появился отдельный модуль-реестр 05-invariants.js и страж guardPlanOps на границе записи плана: любая операция (создание, изменение, удаление) проходит через реестр. В шапке модуля написано, зачем он: «Правило „автоматика не лезет в замороженный день“ возвращалось тикетами трижды за четыре дня, потому ило в трёх разных местах одной функции и не действовало на остальные пути записи. Здесь оно ОДНО, проверяемое машиной и покрытое тестом на все входы». В CLAUDE.md из этого выросло требование к процессу: новое жёсткое правило добавляется одним PR сразу в три места — текстом в §15 ТЗ, кодом в реестр и таблицей «входы × правила» в тест. Формулировка, которую автор повторяет чаще всего: правило, которого нет в реестре, не соблюдается. Догма не нарушается, её можно только не прочитать.
Предупреждение «не используй форму dreq/{source} t=<targetTableId>» агент проигнорировал: справочники снова стали подчинёнными таблицами.
Третий дефект — правило написано прозой. Прозаический текст в инструкции допускает несколько толкований, и агент выбирает то, которое проще исполнить. Пересказ объяснения для человека в виде предостережения не работает: объяснение для человека уже существовало и работало, не работал его пересказ. Формулировка задачи на переписывание раздела 2.5 стоит цитирования: «описать различие и правила, как это сделано в блоге для человека, но языком, понятным LLM, чтобы она больше не путалась». То есть инструкция для агента должна быть не сокращённым пересказом человеческого текста, а отдельным документом с однозначными формулировками и проверками.
Деталь, которая стоила отдельного обсуждения с заказчиком: реестр ограничивает actor: 'auto', то есть автоматику. Ручное действие оператора правило не блокирует — человек по-прежнему может зайти в замороженный день. Это осознанное решение: реестр защищает от автоматических операций, а не от ручных. Автор не приводит замеров и не обещает волшебных промптов. Работает скучное: форма правила, место правила и наличие у него проверки. Всё, на что он ссылается, лежит в публичном репозитории — CLAUDE.md в корне, база знаний по платформе в docs/kb/, полный цикл разработки приложения в docs/integram-app-workflow.md.

