docs(agents): контракт скиллов — трекер, метки триажа, доки и нейминг
- Зачем:
- инженерные скиллы (to-tickets, triage, wayfinder, domain-modeling) ждут
репо-локальную настройку; без неё они не знают, чем заводить issues и
какими метками размечать. Дока трекера жила ссылкой на репозиторий
предшественника — внешняя зависимость на месте источника истины.
- Что:
- заведён docs/agents/: issue-tracker.md (Gitea через tea, команды,
wayfinding, отдельный раздел про то, что «Закрывает #NN» issue не
закрывает), triage-labels.md (пять канонических меток без переименований)
и domain.md (один контекст, CONTEXT.md и docs/adr/).
- в AGENTS.md добавлен раздел «Agent skills» со ссылками на эти файлы,
ссылка на доку предшественника заменена локальной.
- в «Структуре» закреплён нейминг: ГГГГ-ММ-ДД-слаг для docs/specs/ и
docs/research/, NNNN-слаг для docs/adr/.
- Проверка:
- tea labels list — все пять меток триажа заведены в репозитории;
- tea api version — Gitea 1.27.0, команды из доки отвечают живьём.
This commit is contained in:
@@ -48,8 +48,7 @@ Airflow) и названия из кода. Если для понятия ес
|
|||||||
|
|
||||||
Трекер — Gitea на `git.dementev.space`, работа через CLI `tea` (логин по
|
Трекер — Gitea на `git.dementev.space`, работа через CLI `tea` (логин по
|
||||||
умолчанию настроен, репозиторий определяется по git remote). Команды и
|
умолчанию настроен, репозиторий определяется по git remote). Команды и
|
||||||
подводные камни описаны в
|
подводные камни — в [`docs/agents/issue-tracker.md`](docs/agents/issue-tracker.md).
|
||||||
[доке предшественника](https://git.dementev.space/ddmitry/clickstream-ch-kafka-superset-demo/src/branch/main/docs/agents/issue-tracker.md).
|
|
||||||
|
|
||||||
- Спека фичи — файл в `docs/specs/`, источник истины, версионируется с кодом.
|
- Спека фичи — файл в `docs/specs/`, источник истины, версионируется с кодом.
|
||||||
- Корневой issue фичи — тонкий: ссылка на спеку и чек-лист дочерних issues
|
- Корневой issue фичи — тонкий: ссылка на спеку и чек-лист дочерних issues
|
||||||
@@ -60,8 +59,33 @@ Airflow) и названия из кода. Если для понятия ес
|
|||||||
- Метки триажа — пять ролей: `needs-triage`, `needs-info`, `ready-for-agent`,
|
- Метки триажа — пять ролей: `needs-triage`, `needs-info`, `ready-for-agent`,
|
||||||
`ready-for-human`, `wontfix`. Карта и её тикеты — метки `wayfinder:*`.
|
`ready-for-human`, `wontfix`. Карта и её тикеты — метки `wayfinder:*`.
|
||||||
|
|
||||||
|
## Agent skills
|
||||||
|
|
||||||
|
### 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/` или в профильных подпапках, не в корне.
|
- Новые документы — в `docs/` или в профильных подпапках, не в корне.
|
||||||
- Состав доков v2 определяется по ходу этапов, набор предшественника не
|
- Состав доков v2 определяется по ходу этапов, набор предшественника не
|
||||||
копируется (спека, раздел 12).
|
копируется (спека, раздел 12).
|
||||||
|
- Имена файлов в `docs/specs/` и `docs/research/` — `ГГГГ-ММ-ДД-краткое-имя.md`:
|
||||||
|
дата создания документа и слаг строчными латинскими буквами через дефис
|
||||||
|
(`2026-07-30-stand-v2-realism.md`). Дата фиксирует, когда документ появился,
|
||||||
|
и при правках не меняется: файлы сортируются по времени, а история живёт
|
||||||
|
в git.
|
||||||
|
- Имена файлов в `docs/adr/` — `NNNN-краткое-имя.md`: сквозной номер из четырёх
|
||||||
|
цифр и слаг (`0001-stand-services.md`). Решения нумеруются подряд, дата
|
||||||
|
в имени не нужна.
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Доки предметной области
|
||||||
|
|
||||||
|
Как скиллам читать документацию репозитория, прежде чем лезть в код.
|
||||||
|
|
||||||
|
## Что прочитать до разбора кода
|
||||||
|
|
||||||
|
- **`CONTEXT.md`** в корне — словарь понятий проекта.
|
||||||
|
- **`docs/adr/`** — решения. Читать те ADR, что касаются области, в которой
|
||||||
|
сейчас работаешь.
|
||||||
|
- **`docs/specs/`** — спеки фич; для этого репозитория спека и есть источник
|
||||||
|
истины по тому, что строим (см. `docs/agents/issue-tracker.md`).
|
||||||
|
|
||||||
|
Если файла нет — **просто идти дальше молча**. Не сообщать об отсутствии и не
|
||||||
|
предлагать создать заранее. Скилл `/domain-modeling` (через `/grill-with-docs`
|
||||||
|
и `/improve-codebase-architecture`) заводит их лениво, когда термин или решение
|
||||||
|
действительно понадобилось зафиксировать.
|
||||||
|
|
||||||
|
## Разметка: один контекст
|
||||||
|
|
||||||
|
Репозиторий одноконтекстный — один `CONTEXT.md` в корне и один `docs/adr/`:
|
||||||
|
|
||||||
|
```
|
||||||
|
/
|
||||||
|
├── CONTEXT.md ← пока не создан, появится по надобности
|
||||||
|
├── docs/
|
||||||
|
│ ├── adr/ ← 0001-stand-services.md
|
||||||
|
│ ├── specs/
|
||||||
|
│ └── research/
|
||||||
|
├── dags/
|
||||||
|
├── infra/
|
||||||
|
└── scripts/
|
||||||
|
```
|
||||||
|
|
||||||
|
Карта контекстов (`CONTEXT-MAP.md` в корне и по `CONTEXT.md` на контекст) —
|
||||||
|
для больших многопакетных репозиториев; здесь она не нужна. Если репозиторий
|
||||||
|
когда-нибудь разъедется на несколько контекстов, разметку менять здесь.
|
||||||
|
|
||||||
|
## Пользоваться словарём
|
||||||
|
|
||||||
|
Если в выводе называешь понятие предметной области (заголовок issue, гипотеза,
|
||||||
|
имя теста, предложение по рефакторингу) — бери термин ровно в том виде, как он
|
||||||
|
записан в `CONTEXT.md`. Не уходить в синонимы, от которых словарь отказался.
|
||||||
|
|
||||||
|
Понятия нет в словаре — это сигнал: либо выдумываешь язык, которого в проекте
|
||||||
|
нет (стоит передумать), либо нашёл настоящий пробел (отметить для
|
||||||
|
`/domain-modeling`).
|
||||||
|
|
||||||
|
## Спорить с ADR вслух
|
||||||
|
|
||||||
|
Если то, что ты предлагаешь, противоречит принятому ADR — сказать об этом прямо,
|
||||||
|
а не переехать решение молча:
|
||||||
|
|
||||||
|
> _Противоречит ADR-0001 (состав сервисов стенда) — но открыть заново стоит,
|
||||||
|
> потому что…_
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# Issue tracker: Gitea
|
||||||
|
|
||||||
|
Задачи этого репозитория живут в Gitea на `git.dementev.space`
|
||||||
|
(`ddmitry/clickstream-data-platform`, это remote `origin`). Все операции —
|
||||||
|
через CLI [`tea`](https://gitea.com/gitea/tea), официальный клиент Gitea; по
|
||||||
|
устройству он близок к `gh` и `glab`. Логин и репозиторий `tea` определяет сам
|
||||||
|
по git remote в текущем каталоге.
|
||||||
|
|
||||||
|
## Перед первым запуском
|
||||||
|
|
||||||
|
- **Бинарник.** Скачивается с `https://dl.gitea.com/tea/<версия>/` (файл
|
||||||
|
`tea-<версия>-linux-amd64` и `.sha256` рядом), кладётся в `~/.local/bin/tea`.
|
||||||
|
Проверка: `tea --version`.
|
||||||
|
- **Вход.** `tea logins add --name git.dementev.space --url
|
||||||
|
https://git.dementev.space`, токен передаётся переменной
|
||||||
|
`GITEA_SERVER_TOKEN` (не аргументом командной строки — он попадёт в историю
|
||||||
|
оболочки). Логин уже добавлен и назначен по умолчанию, так что `tea` работает
|
||||||
|
из любого каталога.
|
||||||
|
- **Скоупы токена:** `read:user` (без него `tea` откажется добавлять логин),
|
||||||
|
`write:issue`, `write:repository`. Токен выпускается в UI: Settings →
|
||||||
|
Applications. Нехватка скоупа выглядит не как «нет прав», а как невнятная
|
||||||
|
ошибка или пустой ответ.
|
||||||
|
- **Прокси.** Домен `dementev.space` должен быть в `NO_PROXY`, иначе запросы
|
||||||
|
уходят в прокси и виснут. В обычной оболочке это делает `proxy-client` из
|
||||||
|
`~/dotfiles`. Если переменная не подхватилась, короткий разовый префикс:
|
||||||
|
`NO_PROXY='*' tea ...`.
|
||||||
|
|
||||||
|
## Команды
|
||||||
|
|
||||||
|
- **Создать issue:** `tea issues create --title "..." --description "..."`.
|
||||||
|
Многострочное тело удобнее собрать heredoc'ом в переменную и подставить
|
||||||
|
как `--description "$BODY"`.
|
||||||
|
- **Прочитать issue:** `tea issues <номер> --comments`.
|
||||||
|
- **Список:** `tea issues list --state open --output json --fields
|
||||||
|
index,title,labels,assignees`. Фильтры: `--labels`, `--assignee`,
|
||||||
|
`--keyword`.
|
||||||
|
- **Комментарий:** `tea comments add <номер> -d "..."`.
|
||||||
|
- **Метки:** `tea issues edit <номер> --add-labels "..."` / `--remove-labels
|
||||||
|
"..."`. Список меток репозитория — `tea labels list`, создать новую —
|
||||||
|
`tea labels create --name "..." --color "..."`.
|
||||||
|
- **Закрыть:** `tea issues close <номер>`. Комментария при закрытии команда не
|
||||||
|
принимает — сначала `tea comments add`, потом `close`.
|
||||||
|
- **Взять в работу:** `tea issues edit <номер> --add-assignees ddmitry`.
|
||||||
|
Сокращения вида `@me` в `tea` нет, имя пишется целиком.
|
||||||
|
- **Чего нет в CLI** — через `tea api <path>`: команда ходит в REST API Gitea
|
||||||
|
уже с сохранённым токеном, например
|
||||||
|
`tea api repos/ddmitry/clickstream-data-platform/issues/18`.
|
||||||
|
|
||||||
|
## Слияние PR не закрывает issue
|
||||||
|
|
||||||
|
Gitea понимает только английские ключевые слова автозакрытия: `closes`,
|
||||||
|
`fixes`, `resolves` (`Closes #13`). Русское «Закрывает #13» в теле PR — обычная
|
||||||
|
ссылка, issue останется открытым. Наступали не раз: последний случай — слияние
|
||||||
|
PR #17, где issue #13 пришлось закрывать руками.
|
||||||
|
|
||||||
|
Порядок после слияния: закрыть задачу (`tea issues close <номер>`) и тикнуть
|
||||||
|
её пункт в чек-листе родительского issue этапа — Gitea чек-листы сама не
|
||||||
|
обновляет.
|
||||||
|
|
||||||
|
## Спека — источник истины
|
||||||
|
|
||||||
|
- Спецификация фичи — файл в `docs/specs/`, версионируется с кодом.
|
||||||
|
- Корневой issue фичи — **тонкий**: ссылка на спеку + чек-лист дочерних issues
|
||||||
|
(`- [ ] #NN`). Содержание спеки в issue не дублируется — истина одна, в git.
|
||||||
|
- Дочерние issues — полноценные самодостаточные постановки: цель, критерии
|
||||||
|
приёмки чекбоксами, границы («что трогать нельзя»), «сначала прочитать»,
|
||||||
|
команды проверки.
|
||||||
|
- Итоговые резолюции и решения — в спеку или ADR тем же PR; issue — рабочая
|
||||||
|
переписка, она не обязана переживать фичу.
|
||||||
|
|
||||||
|
## Когда скилл говорит «опубликовать в issue tracker»
|
||||||
|
|
||||||
|
Создать issue в Gitea: `tea issues create ...`.
|
||||||
|
|
||||||
|
## Когда скилл говорит «достать тикет»
|
||||||
|
|
||||||
|
`tea issues <номер> --comments`.
|
||||||
|
|
||||||
|
## PR как поверхность триажа
|
||||||
|
|
||||||
|
**Нет** — одиночный учебный репозиторий, внешних PR не ждём. (Если включить —
|
||||||
|
`/triage` начнёт гонять PR через те же метки и состояния командами
|
||||||
|
`tea pulls ...`.)
|
||||||
|
|
||||||
|
## Wayfinding-операции
|
||||||
|
|
||||||
|
Используются `/wayfinder`. Карта — один issue, тикеты — дочерние issues.
|
||||||
|
|
||||||
|
- **Карта**: issue с меткой `wayfinder:map` (Notes / Decisions-so-far / Fog
|
||||||
|
в теле).
|
||||||
|
- **Дочерний тикет**: вложенных issues в Gitea нет, поэтому связь держится
|
||||||
|
двумя ссылками — пункт списка `- [ ] #NN` в теле карты и строка
|
||||||
|
`Part of #<карта>` в начале тела тикета. Метки: `wayfinder:<тип>`
|
||||||
|
(`research` / `prototype` / `grilling` / `task`).
|
||||||
|
- **Блокировки**: нативные зависимости Gitea — единственный источник истины,
|
||||||
|
текстовых строк `Blocked by:` в телах тикетов нет. В CLI их команд нет,
|
||||||
|
работаем через `tea api` (`{owner}` и `{repo}` подставляются из текущего
|
||||||
|
репозитория):
|
||||||
|
- добавить блокер: `tea api repos/{owner}/{repo}/issues/<n>/dependencies
|
||||||
|
-F index=<блокер> -f owner=ddmitry -f repo=clickstream-data-platform`
|
||||||
|
— поля `owner` и `repo` обязательны, без них API отвечает
|
||||||
|
«repository does not exist»;
|
||||||
|
- кто блокирует тикет: `GET .../issues/<n>/dependencies`;
|
||||||
|
- кого блокирует тикет: `GET .../issues/<n>/blocks`;
|
||||||
|
- снять блокировку: тот же путь методом `DELETE` с тем же телом.
|
||||||
|
|
||||||
|
Тикет разблокирован, когда у всех блокеров `state == "closed"`.
|
||||||
|
- **Фронтир**: открытые дети карты минус заблокированные и назначенные; первый
|
||||||
|
в порядке карты. Блокеры проверяются запросом `dependencies` по каждому
|
||||||
|
кандидату.
|
||||||
|
- **Взять в работу**: `tea issues edit <n> --add-assignees ddmitry` — первая
|
||||||
|
запись за сессию.
|
||||||
|
- **Закрыть**: `tea comments add <n> -d "<ответ>"`, затем `tea issues close
|
||||||
|
<n>`, затем указатель на контекст (суть + ссылка) в Decisions-so-far карты.
|
||||||
|
|
||||||
|
## Что проверено и когда
|
||||||
|
|
||||||
|
2026-07-31: Gitea 1.27.0 (`tea api version`), `tea` 0.15.0. Живыми запросами по
|
||||||
|
этому репозиторию проверены `tea labels list` и `tea issues list`. Остальной
|
||||||
|
набор команд, флагов и приёмы с `tea api` перенесены из доки
|
||||||
|
предшественника — там они снимались с `tea <команда> --help` установленного
|
||||||
|
бинарника и проверялись живыми запросами 2026-07-29. При обновлении `tea` стоит
|
||||||
|
перечитать `--help`: набор флагов между версиями менялся.
|
||||||
|
|
||||||
|
## Архив
|
||||||
|
|
||||||
|
- Трекер предшественника — репозиторий
|
||||||
|
[`ddmitry/clickstream-ch-kafka-superset-demo`](https://git.dementev.space/ddmitry/clickstream-ch-kafka-superset-demo).
|
||||||
|
Задачи оттуда сюда не переносились: платформа v2 начата с чистого трекера.
|
||||||
|
- До 2026-07-26 задачи предшественника жили в GitHub Issues
|
||||||
|
(`dementev-dev/…`); аккаунт заблокирован, номера воссозданы в Gitea один
|
||||||
|
в один.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Метки триажа
|
||||||
|
|
||||||
|
Скиллы говорят о пяти канонических ролях триажа. Эта таблица переводит роли в
|
||||||
|
метки, которые реально заведены в трекере репозитория.
|
||||||
|
|
||||||
|
| Роль в скиллах | Метка у нас | Значение |
|
||||||
|
| ----------------- | ----------------- | ------------------------------------------- |
|
||||||
|
| `needs-triage` | `needs-triage` | Задачу надо оценить, решение не принято |
|
||||||
|
| `needs-info` | `needs-info` | Ждём уточнений от автора |
|
||||||
|
| `ready-for-agent` | `ready-for-agent` | Постановка полная, можно отдавать агенту |
|
||||||
|
| `ready-for-human` | `ready-for-human` | Нужен человек |
|
||||||
|
| `wontfix` | `wontfix` | Делать не будем |
|
||||||
|
|
||||||
|
Имена совпадают с каноническими: переименований нет. Когда скилл говорит про
|
||||||
|
роль («поставь метку готовности для агента»), берём строку из правой колонки.
|
||||||
|
|
||||||
|
Все пять меток уже созданы в Gitea (проверено `tea labels list` 2026-07-31) —
|
||||||
|
заводить их заново не нужно. Кроме них в репозитории живут метки карты
|
||||||
|
`wayfinder:*` (`map`, `research`, `prototype`, `grilling`, `task`); к триажу они
|
||||||
|
отношения не имеют, ими размечает `/wayfinder`.
|
||||||
|
|
||||||
|
Если вокабуляр меток поменяется — править правую колонку здесь, а не в скиллах.
|
||||||
Reference in New Issue
Block a user