Files
clickstream-data-platform/AGENTS.md
T
ddadmin 466acafce6 docs(handbook): интерактивная карта слоев хранилища
Зачем: путеводитель рассказывает путь данных через слои словами, а карта
дает его увидеть и потрогать: у одного смысла в каждом слое свое имя и своя
поверхность, а переносят данные три разных механизма — матвью непрерывно,
даг пачкой, представление без копии. Постановка — тикет #222, форма —
резолюция #208 (один самодостаточный HTML, исходники рядом).

Что: docs/handbook/architecture-map.html — готовая карта; исходники в
docs/handbook/architecture-map/ (map.yaml — слои, узлы, стрелки, карточки;
template.html — разметка, стили, скрипт; render.py — сборка и --check;
README.md). Щелчок по узлу открывает карточку и подсвечивает путь, щелчок по
стрелке — кто и каким SQL переносит данные; переключатель потока приглушает
чужую часть карты. Ссылки карточек ведут в справочники и DDL на Gitea.
Путеводитель и глава о хранилище ведут на карту; make lint проверяет ruff
для сборщика и свежесть рендера; testing.md и AGENTS.md обновлены.

Проверка: uv run docs/handbook/architecture-map/render.py --check и
make lint зеленые; внешних запросов в HTML нет; ссылки и якоря карточек
сверены с Gitea; карта прощелкана в headless Chromium на ширинах
1280–1920: подсветка пути, фильтр, Esc, карточки узлов и стрелок.
Ревью: постановка — Opus; реализация — Codex (Sol), два слепых ревью Opus
(уместность и код), вычитка прозы Sol.
2026-09-03 03:40:14 -04:00

180 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md
Короткий контракт для работы в репозитории учебной дата-платформы кликстрима.
## Цель репозитория
Проект учебный: учебная ценность разработок — одна из его базовых ценностей.
Стенд строится по спеке
[«Боевой реализм стенда (v2)»](docs/specs/2026-07-30-stand-v2-realism.md).
Отсюда вопрос к любой доработке — коду, проверке, документу: **чему на ней
научится менти?** Ответ называется одной фразой до того, как писать. Не
складывается фраза — это вопрос владельцу, а не строчка кода: проверки в этом
репозитории однажды уже переросли продукт.
**Усложнение не бесплатно, и платит за него учебная ценность.** Чем сложнее
стенд, тем хуже он как учебный материал: внимание менти конечно, и каждая
конструкция, которую он обязан расшифровать по дороге к уроку, списывается с
этого счёта. Поэтому вопрос выше имеет вторую половину: **что менти платит,
чтобы это прочесть, и что получает взамен?** Ответ «вопрос — и ничего»
означает, что писать не нужно.
Оборонительный код дороже прочего. Читатель не отличает «стоит здесь, потому
что есть настоящая опасность» от «стоит здесь, потому что кто-то был
остроумен», — и предполагает первое. Лишний сторож не безобиден: он
утверждает, будто опасность заслуживает внимания, и этим врёт. Особенно это
касается защиты от ошибки, которую человек делает сам себе и тут же видит:
разбирательство с ней и есть урок, отнимать его не надо.
Ревью само по себе умеет только прибавлять: каждая находка просится в правку,
и за прогон их набираются десятки. Поэтому перед приёмкой заметной работы
идёт отдельный **проход на вычитание** — с правом только резать и с явным
списком неприкосновенного. Сомнение «резать или нет» решается в пользу
реза: вещь, которая себя не защитила, себя не защитила.
## Кому что поручать
Читатель здесь не побочный потребитель, а тот, ради кого стенд существует:
код, комментарии и документы и есть продукт. Поэтому всё, что человек будет
читать и разбирать, пишет модель с чувством меры — сейчас это Opus. Codex
берёт техническую работу без вкусовых решений: миграции, разбор журналов и
объёмного вывода, обход репозитория, повторяющиеся правки. Там его запас
лимитов работает на нас, а экономить их на читаемом коде — экономия ложная:
переписывать выйдет дороже, чем сразу написать хорошо.
Делить работу между ними стоит не целыми задачами, а подзадачами, и решать
это при планировании. Вкусовая часть идёт первой: она задаёт форму, имена и
границы, под которые механическая потом подстраивается.
Ревью держит две линии, и назначаются они по разным основаниям. Линию
дефектов ведёт тот, кто код не писал: здесь работает различие — разные
родословные промахиваются по-разному. Линию уместности назначает не
различие, а умение: её ведёт модель со вкусом, даже если она же писала код.
Отдать её «второму исполнителю» ради независимости заманчиво, но модель без
вкуса на этой линии бесполезна.
Плата у такого решения есть: общая слепота автора и ревьюера одной
родословной проходит дважды. Гасится она свежей сессией без общего контекста
и явно другой линзой, но не до конца — поэтому там, где цена ошибки этого не
терпит, линию уместности берёт третья модель.
## Язык
Пиши на ясном русском языке. Иностранные слова оставляй только там, где у
термина нет устоявшегося русского аналога: имена технологий (Kafka, ClickHouse,
Airflow) и названия из кода. Если для понятия есть обычное русское слово —
используй его, не выдумывай транслитерации.
Документы и комментарии держи короткими и понятными читателю, который их не
писал: простые слова, короткие фразы, сложную мысль поясняй при первом
упоминании. Если понятность и буквальная точность спорят — выбирай понятность.
Внутренние рассуждения и промежуточные пометки по ходу работы веди на
английском — он экономнее по токенам. На русском остаётся всё, что видит и
хранит проект: итоговые ответы, документы, комментарии в коде и SQL, сообщения
коммитов.
## Код и данные
- Python — только через `uv`; проверка и формат — `ruff`. Цель `make lint`
есть за двумя дверями и охватывает разное: в корне — код стенда, в
`generator/` — код генератора. Правишь даги или Superset — зови корневую,
правишь генератор — зови из `generator/`.
- Изменения держать минимальными и в границах задания.
- `make clean` полностью удаляет постоянное состояние стенда. Перед этой
командой назови состояние вне прикладного мира, которое требуется удалить,
и объясни, почему `make rebuild-storage` его не удаляет. При изменении DDL
или проверке на чистых данных по умолчанию используй адресную очистку либо
`make rebuild-storage`.
- Куда класть новую проверку, что утверждает каждая цель `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/labs/` — слаг строчными латинскими буквами через дефис
(`top-pages-daily.md`), индекс папки — `README.md`. Здесь живут ТЗ учебных
заданий. Ни даты, ни номера: задание — не событие истории, а живой документ,
и правится он вместе с тем, о чем говорит. Слаг называет предмет задания.
- Имена файлов в `docs/handbook/` — слаг строчными латинскими буквами через
дефис, индекс папки — `README.md`. Здесь живет путеводитель по стенду:
учебные главы для менти. Ни дат, ни номеров: глава — живой документ и
правится вместе с тем, что описывает. Исходники интерактивной карты лежат
подпапкой `architecture-map/`, а ее рендер — файлом `architecture-map.html`
рядом с главами.
- Имена файлов в `docs/adr/` — `NNNN-краткое-имя.md`: сквозной номер из четырёх
цифр и слаг (`0001-stand-services.md`). Решения нумеруются подряд, дата
в имени не нужна.
- Имена файлов в `docs/architecture/` — слаг строчными латинскими буквами через
дефис (`storage.md`). Здесь живут рабочие справочники по зонам
ответственности: не событие истории и не решение, а текущее устройство —
один файл на зону, правится по мере постройки. Крупный компонент живёт
подпапкой: индекс `README.md` и файл на каждую часть устройства
(`architecture/orders/`), имена по тому же правилу
([ADR 0011](docs/adr/0011-component-docs.md)).