Анатомия репозитория, готового для ИИ-агента: навыки, правила и документация рядом с кодом

Два предыдущих поста объясняли почему: Документация в эпоху ИИ показал, что теперь документацию читает LLM при каждой задаче, а D3 превратил это в процесс разработки. Этот пост — про что именно: проход по реальному репозиторию, обустроенному под агента, файл за файлом, с одним вопросом к каждому слою — что теперь умеет ИИ, чего не мог раньше?

Объект — продакшен Android-приложение: 100+ Gradle-модулей, архитектура «модуль на фичу», два продуктовых флейвора. Достаточно большое, чтобы никто не держал его целиком в голове, — а именно в этих условиях способность агента ориентироваться без догадок перестаёт быть приятным бонусом и становится сутью дела.

У репозитория две половины, решающие две разные задачи:

  • .claude/ говорит агенту, как здесь работать, — соглашения, процедуры, стандарты ревью.
  • docs/ говорит агенту, что делает система, — спецификации поведения, карты модулей, контракты аналитики.

Ни одна не работает без другой. Навык, знающий, как реализовать фичу, всё равно должен прочитать документ, чтобы узнать, что это за фича. Разберём по порядку.

Половина первая: .claude/ — как агент работает

1
2
3
4
5
6
.claude/
├── rules/ 17 тематических файлов соглашений (рубрика)
├── skills/ 24 именованных воркфлоу (процедуры)
├── agents/ 10 специализированных суб-агентов (ревьюеры)
├── hooks/ shell-хуки на edit/stop (страховка)
└── scripts/ детерминированные помощники (не-ИИ работа)

Правила — соглашения команды в виде чек-листа

.claude/rules/*.md — узкие однотемные файлы: mvi-architecture.md, navigation.md, app-result.md, webview.md, analytics.md и так далее. Каждый кодифицирует одно соглашение, и формат важнее, чем кажется. Это не эссе — это рубрики с парами ✅ верно / ❌ неверно, с которыми агент сверяется по образцу.

Вот реальный app-result.md, описывающий, как в кодовой базе сцепляются операции, способные упасть:

1
2
3
4
5
// ❌ НЕВЕРНО: map с лямбдой, возвращающей AppResult → AppResult<AppResult<Profile>>
val nested = result.map { user -> fetchUserProfile(user.id) }

// ✅ ВЕРНО: flatMap «разворачивает» вложенный результат
val profile = result.flatMap { user -> fetchUserProfile(user.id) }

Раскрытая способность: ИИ пишет код по вашим соглашениям, а не по статистическому среднему GitHub. Без этого файла модель выдаёт идиоматичный, но обобщённый Kotlin. С ним — код, похожий на остальной этот репозиторий: internal-видимость, никаких публичных констант, flatMap вместо ручного when. Соглашение едет вместе с кодом, поэтому оно соблюдается при каждом запуске, для каждого участника — человека или модели.

Самое изящное — обратная связь: навык /review-and-rule наблюдает, как кодовая база на самом деле обрабатывает паттерн, и сам пишет или обновляет файл правила. Соглашения, найденные на ревью, становятся правилами, применяемыми при следующей реализации. Рубрика поддерживает себя сама.

Навыки — процедуры, а не промпты

Навык — это именованный многофазный воркфлоу, вызываемый через /skill-name. В этом репозитории их 24. Это и есть разница между «попросить агента реализовать фичу» и «вручить ему реальный регламент команды».

/implement-feature — показательный пример. Он не просто пишет код, а проходит фазы:

  1. Интервью — задаёт фиксированный набор вопросов о требованиях через структурированные запросы.
  2. Дизайн — выводит из ответов MVI-форму (State / Action / Event / Reducer).
  3. Каркас — генерирует пару модулей api-* + feature-*.
  4. Реализация — пишет реальную логику и Compose UI по правилам выше.
  5. Саморевью — вызывает суб-агента code-reviewer перед возвратом результата.

Другие навыки острее: /task-worker берёт Jira-тикет и проводит его от начала до конца с тремя циклами авто-починки; /check-coverage запускает JaCoCo, находит пробелы и пишет тесты пачками, пока не достигнет цели; /discovery-to-srs превращает черновик в структурированную спецификацию и отдаёт независимому агенту на валидацию.

Раскрытая способность: ИИ выполняет процесс, а не импровизирует его. Импровизация — это там, где агенты «уплывают»: каждый запуск заново изобретает подход, и качество — подбрасывание монетки. Навык фиксирует шаги, оставляя содержание модели. Результат — воспроизводимость: /implement-feature сегодня выдаёт ту же форму модуля, что и месяц назад, потому что фазы фиксированы, хотя код новый.

Суб-агенты — специалисты со свежим контекстом и узкой рубрикой

В .claude/agents/ — 10 определений суб-агентов, большинство из них ревьюеры: pr-review-architecture, pr-review-compose, pr-review-performance, pr-review-tests, pr-review-package-structure, pr-review-code-quality. Навык /review-pr-advanced запускает все шесть параллельно, каждого в своём контекстном окне, с одной-единственной задачей.

Промпт архитектурного ревьюера — плотный чек-лист: «Reducer вызывает Use Case, а не Repository», «каждый класс реализации должен быть internal», «навигация идёт через интерфейс Router», — и ему явно сказано не проверять форматирование или производительность Compose, потому что за это отвечают другие агенты.

Раскрытая способность: глубина без размывания. Один агент, которого просят «отревьюить этот PR», распыляет внимание, а его контекст забивается шумом. Шесть специалистов, каждый с фокусной рубрикой и чистым контекстом, ловят то, что упускает универсал, — и работают одновременно, так что по времени это одно ревью, а не шесть. Это форма найти → специализировать → проверить, которую один большой промпт не повторит.

Хуки и скрипты — то, что не должно быть ИИ

Ещё два слоя замыкают картину. Хуки (post-edit-review-reminder.sh, pre-stop-review-check.sh) — это shell-скрипты, которые харнесс запускает при редактировании и перед остановкой агента; они подталкивают к шагу ревью, чтобы его нельзя было молча пропустить. Скрипты (парсеры XML-отчётов JaCoCo, генераторы индексов документации) — обычный Python: детерминированная работа, которую расточительно и ненадёжно делать моделью.

Раскрытая способность: агент знает, о чём не надо думать. Разбор XML-отчёта о покрытии не требует языковой модели; соблюдение правила «ревью перед остановкой» не должно зависеть от того, вспомнит ли о нём модель. Вынос этой работы в хуки и скрипты делает систему дешевле и надёжнее — ИИ тратит токены на суждения, а не на бухгалтерию.

Половина вторая: docs/ — что делает система

Продуктовая документация живёт во вложенном git-репозитории, склонированном в docs/, а само содержимое — в docs/docs/. Вложенность сделана осознанно (про почему именно в репозитории — ниже), но интересна как раз структура внутри:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docs/docs/
├── INDEX.md модуль → фича (генерируется)
├── llms.txt выверенный манифест для агентов
├── STYLE.md машинно-проверяемые соглашения
├── GLOSSARY.md акронимы (WL, LP, SRS, TNB…)
├── features/
│ └── <Feature>/
│ ├── README.md индекс папки (генерируется)
│ ├── modules.md карта модулей (источник истины)
│ ├── <Feature>.srs.md основная спека
│ ├── analytics/ спеки событий
│ ├── _drafts/ в работе (status: draft)
│ └── _archive/ устаревшее
└── technical/ сквозной справочник

INDEX.md — таблица соответствий, убивающая слепой поиск

INDEX.md сопоставляет каждый из ~265 модулей кода с фичей, к которой он относится:

1
2
3
| `:features:feature-alerts-feed`         | Alerts            |
| `:features:feature-instrument-tab-news` | Instrument screen |
| `:services:service-deep-links` | Deep links |

Важно: секция «модуль → фича» генерируется из modules.md каждой фичи Python-скриптом — поэтому она не может разойтись с реальностью из-за ручной правки.

Раскрытая способность: первый ход агента — это поиск по индексу, а не перебор. Бросьте модель в репозиторий из 100 модулей без индекса, и «где живёт лента алертов?» превращается в веер grep’ов и догадок. С INDEX.md — это один прыжок: модуль → папка фичи → спека. Каждый навык в репозитории начинается с этого же прыжка. 45 папок фич — это разница между агентом, который исследует, и агентом, который извлекает.

llms.txt и STYLE.md — контракт для машинных читателей

llms.txt — это формирующееся соглашение о точке входа для ИИ: выверенный манифест, указывающий на основную спеку каждой фичи, причём черновики и архив намеренно исключены, чтобы агент сначала читал авторитетный документ.

STYLE.md — на мой взгляд, самое недооценённое. Это гайд по стилю, который реально проверяем: каждый документ обязан объявить type из фиксированного перечня (srs, overview, api, analytics…), каждая спека обязана покрывать три состояния пользователя (гость / зарегистрированный / с подпиской), имена файлов следуют канону — и CI-гейт (check-doc-filenames.py, run-quality-gates.py) роняет сборку, когда это не так.

Раскрытая способность: документы, написанные ИИ, выходят однородными. Когда /discovery-to-srs или Jira-пайплайн генерирует спеку, STYLE.md — это схема, под которую она пишется; так машинно-созданные документы получаются той же формы, что и написанные вручную, и следующий агент, читающий их, точно знает, куда смотреть. Гайд, который человек просто читает, — рекомендательный; гайд, который есть перечень плюс CI-гейт, — контракт, соблюдаемый обеими сторонами.

modules.md и папки жизненного цикла — честность во времени

modules.md каждой фичи — это источник истины о том, какой код к ней относится, и правило такое: добавил модуль в коде — обнови modules.md в том же PR. Подпапки _drafts/ и _archive/, управляемые полем status, не дают работе-в-процессе и мёртвым документам засорять то, что агент считает авторитетным.

Раскрытая способность: агент может доверять тому, что читает. Самый дорогой режим отказа для документ-ориентированного ИИ — уверенно действовать по устаревшей спеке: ошибки не будет, он просто сделает не то. Обновления модулей в том же PR и явный статус жизненного цикла — это дешёвый, невзрачный механизм, не дающий «в документации написано X» и «код делает X» разойтись.

Соединительная ткань

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

1
2
3
4
5
6
Jira-тикет  →  INDEX.md (модуль → фича)
→ modules.md (какие модули)
→ <Feature>.srs.md (задокументированное поведение)
→ реализация под управлением .claude/rules/*
→ ревью через специализированных суб-агентов
→ /update-docs помечает, какие спеки устарели

task-worker проживает этот цикл от и до. Он никогда не гадает, где фича и как она должна себя вести, — он ищет и то и другое, строит против задокументированного контракта, реализует под правилами, ревьюит со специалистами, а затем проверяет, не сделали ли его же изменения документацию устаревшей. Системы из первого поста — Q&A-бот Doc-Chat, пайплайн Jira→Docs — это просто ещё потребители той же структуры. Они работают, потому что индекс, спеки и правила уже существуют, чтобы их читать.

Что теперь умеет ИИ — коротко

Слой Какую способность раскрывает
.claude/rules/ Пишет код по вашим соглашениям, а не по среднему GitHub
.claude/skills/ Выполняет воспроизводимый процесс, а не импровизирует
.claude/agents/ Глубокое параллельное ревью — специалисты, а не один уставший универсал
.claude/hooks + scripts/ Тратит токены на суждения; сгружает рутину
docs/INDEX.md Извлекает по индексу вместо слепого поиска
docs/llms.txt + STYLE.md Читает нужный документ; пишет новые в единой форме
modules.md + жизненный цикл Доверяет тому, что читает — документация не гниёт молча

Почему именно в репозитории

Каждая выгода выше зависит от того, что этот контекст живёт в репозитории, а не в Confluence или вики. Четыре причины, и все они усиливают друг друга:

  • Автозагрузка. CLAUDE.md и .claude/ подтягиваются в каждую сессию агента без всякой настройки. Вики-страницу нужно найти, скачать и вставить — а значит, обычно её не вставляют.
  • Привязка к версии. Документация на том же коммите, что и код. Переключитесь на ветку полугодовой давности — получите спеки и правила именно той ветки, без гаданий «какая версия этой Confluence-страницы соответствует этому тегу?».
  • Тот же diff. Изменение поведения и обновление его документа едут в одном PR и ревьюятся вместе. /update-docs существует именно чтобы держать эту связь тугой. Confluence обновляют неделями позже, если вообще.
  • Грепается и дружит с кэшем. Простой текст на живой файловой системе означает, что агент может Grep по текущему состоянию — без индекса эмбеддингов, который надо пересинхронизировать (аргумент «без векторной БД» из первого поста). А малоизменчивый простой текст держит промпт-кэш тёплым, что на масштабе — реальная статья расходов.

Итог

Репозиторий, готовый для агента, — это не один большой умный промпт. Это две скучные слоистые половины: .claude/, кодирующая, как работает команда, и docs/, кодирующая, что делает система, — соединённые дисциплиной разрешить, прочитать, действовать. Каждый файл сам по себе мал и невзрачен; вместе они — разница между ИИ, который исследует вашу кодовую базу, и ИИ, который ею управляет.

Вложение реальное, но это то же вложение, что делает кодовую базу понятной новому senior-инженеру, — только теперь вы делаете его один раз и сразу на все будущие запуски агента. Начните с трёх файлов из первого поста (CLAUDE.md, несколько правил, индекс), выпустите один навык и дайте /review-and-rule вырастить остальное из того, что ваши ревью уже знают.

Что почитать дальше