# AGENTS.md Короткий контракт для работы в репозитории учебной дата-платформы кликстрима. ## Цель репозитория Проект учебный: учебная ценность разработок — одна из его базовых ценностей. Стенд строится по спеке [«Боевой реализм стенда (v2)»](docs/specs/2026-07-30-stand-v2-realism.md). Отсюда вопрос к любой доработке — коду, проверке, документу: **чему на ней научится менти?** Ответ называется одной фразой до того, как писать. Не складывается фраза — это вопрос владельцу, а не строчка кода: проверки в этом репозитории однажды уже переросли продукт. **Усложнение не бесплатно, и платит за него учебная ценность.** Чем сложнее стенд, тем хуже он как учебный материал: внимание менти конечно, и каждая конструкция, которую он обязан расшифровать по дороге к уроку, списывается с этого счёта. Поэтому вопрос выше имеет вторую половину: **что менти платит, чтобы это прочесть, и что получает взамен?** Ответ «вопрос — и ничего» означает, что писать не нужно. Оборонительный код дороже прочего. Читатель не отличает «стоит здесь, потому что есть настоящая опасность» от «стоит здесь, потому что кто-то был остроумен», — и предполагает первое. Лишний сторож не безобиден: он утверждает, будто опасность заслуживает внимания, и этим врёт. Особенно это касается защиты от ошибки, которую человек делает сам себе и тут же видит: разбирательство с ней и есть урок, отнимать его не надо. Ревью само по себе умеет только прибавлять: каждая находка просится в правку, и за прогон их набираются десятки. Поэтому перед приёмкой заметной работы идёт отдельный **проход на вычитание** — с правом только резать и с явным списком неприкосновенного. Сомнение «резать или нет» решается в пользу реза: вещь, которая себя не защитила, себя не защитила. ## Кому что поручать Читатель здесь не побочный потребитель, а тот, ради кого стенд существует: код, комментарии и документы и есть продукт. Поэтому всё, что человек будет читать и разбирать, пишет модель с чувством меры — сейчас это Opus. Codex берёт техническую работу без вкусовых решений: миграции, разбор журналов и объёмного вывода, обход репозитория, повторяющиеся правки. Там его запас лимитов работает на нас, а экономить их на читаемом коде — экономия ложная: переписывать выйдет дороже, чем сразу написать хорошо. Делить работу между ними стоит не целыми задачами, а подзадачами, и решать это при планировании. Вкусовая часть идёт первой: она задаёт форму, имена и границы, под которые механическая потом подстраивается. Ревью держит две линии, и назначаются они по разным основаниям. Линию дефектов ведёт тот, кто код не писал: здесь работает различие — разные родословные промахиваются по-разному. Линию уместности назначает не различие, а умение: её ведёт модель со вкусом, даже если она же писала код. Отдать её «второму исполнителю» ради независимости заманчиво, но модель без вкуса на этой линии бесполезна. Плата у такого решения есть: общая слепота автора и ревьюера одной родословной проходит дважды. Гасится она свежей сессией без общего контекста и явно другой линзой, но не до конца — поэтому там, где цена ошибки этого не терпит, линию уместности берёт третья модель. ## Язык Пиши на ясном русском языке. Иностранные слова оставляй только там, где у термина нет устоявшегося русского аналога: имена технологий (Kafka, ClickHouse, Airflow) и названия из кода. Если для понятия есть обычное русское слово — используй его, не выдумывай транслитерации. Документы и комментарии держи короткими и понятными читателю, который их не писал: простые слова, короткие фразы, сложную мысль поясняй при первом упоминании. Если понятность и буквальная точность спорят — выбирай понятность. Внутренние рассуждения и промежуточные пометки по ходу работы веди на английском — он экономнее по токенам. На русском остаётся всё, что видит и хранит проект: итоговые ответы, документы, комментарии в коде и SQL, сообщения коммитов. ## Код и данные - Python — только через `uv`; проверка и формат — `ruff`. Цель `make lint` есть за двумя дверями и охватывает разное: в корне — код стенда, в `generator/` — код генератора. Правишь одно — зови ту. - Изменения держать минимальными и в границах задания. - Куда класть новую проверку, что утверждает каждая цель `make` и почему смоук обязан оставаться быстрым — [`docs/architecture/testing.md`](docs/architecture/testing.md). - Секреты не коммитить: настройки — через `.env`, образец — `.env.example`. - При изменении инфраструктуры или DDL обновлять документацию тем же PR. - Коммиты — Conventional Commits: заголовок `type(scope): результат`, тело на русском по схеме Зачем / Что / Проверка. - «Грязные» записи не должны валить пайплайн: ошибки разбора уходят в таблицы `*_errors`. - Данные не читать целиком без необходимости: по умолчанию малый срез. Для демо и тестов быстрый повторяемый прогон важнее полноты данных. ## Проверка API через MCP Context7 (обязательно) Для спорных или меняющихся API (Airflow и провайдеры, DDL ClickHouse) сначала уточнять актуальную версию: `resolve-library-id` -> `query-docs`. Принятое решение кратко фиксировать в коде или документации: что проверили и почему выбрали этот вариант. ## Задачи Трекер — Gitea на `git.dementev.space`, работа через CLI `tea` (логин по умолчанию настроен, репозиторий определяется по git remote). Команды и подводные камни — в [`docs/agents/issue-tracker.md`](docs/agents/issue-tracker.md). - Спека фичи — файл в `docs/specs/`, источник истины, версионируется с кодом. - Корневой issue фичи — тонкий: ссылка на спеку и чек-лист дочерних issues (`- [ ] #NN`). Содержание спеки в issue не дублируется. - Дочерние issues — самодостаточные постановки: цель, критерии приёмки чекбоксами, границы, «сначала прочитать», команды проверки. - Итоговые решения переносятся в спеку или ADR тем же PR. - Метки триажа — пять ролей: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. Карта и её тикеты — метки `wayfinder:*`. ## Agent skills ### Развилки решений Существенные развилки — в грилинге, на тикетах wayfinder-карт и вне их — вести через скилл `brainstorm-with-docs`: сначала веер вариантов, потом конвергенция. Состав веера и запись отклонённых вариантов — в самом скилле. ### Issue tracker Задачи — в Gitea на `git.dementev.space`, все операции через CLI `tea`. См. [`docs/agents/issue-tracker.md`](docs/agents/issue-tracker.md). ### Triage labels Пять канонических меток триажа без переименований, уже заведены в трекере. См. [`docs/agents/triage-labels.md`](docs/agents/triage-labels.md). ### Domain docs Один контекст: `CONTEXT.md` в корне и `docs/adr/`. См. [`docs/agents/domain.md`](docs/agents/domain.md). ## Структура - Новые документы — в `docs/` или в профильных подпапках, не в корне. - Состав доков v2 определяется по ходу этапов, набор предшественника не копируется (спека, раздел 12). - Имена файлов в `docs/specs/` и `docs/research/` — `ГГГГ-ММ-ДД-краткое-имя.md`: дата создания документа и слаг строчными латинскими буквами через дефис (`2026-07-30-stand-v2-realism.md`). Дата фиксирует, когда документ появился, и при правках не меняется: файлы сортируются по времени, а история живёт в git. - Имена файлов в `docs/formats/` — слаг строчными латинскими буквами через дефис (`clickstream-event.md`). Ни даты, ни номера: документ не событие истории, а текущее описание живого формата — и собирается из кода, а не пишется руками. - Имена файлов в `docs/adr/` — `NNNN-краткое-имя.md`: сквозной номер из четырёх цифр и слаг (`0001-stand-services.md`). Решения нумеруются подряд, дата в имени не нужна. - Имена файлов в `docs/architecture/` — слаг строчными латинскими буквами через дефис (`storage.md`). Здесь живут рабочие справочники по зонам ответственности: не событие истории и не решение, а текущее устройство — один файл на зону, правится по мере постройки.