# Issue tracker: Gitea

Задачи этого репозитория живут в Gitea на `git.dementev.space`
(`ddmitry/clickstream-ch-kafka-superset-demo`, это 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`; для агента в t3 — блок `environment` в
  `~/.t3/userdata/settings.json`. Если переменная не подхватилась, короткий
  разовый префикс: `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-ch-kafka-superset-demo/issues/17`.

## Спека — источник истины

- Спецификация фичи — файл в `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-ch-kafka-superset-demo`
    — поля `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-29: Gitea 1.27.0, `tea` 0.15.0. Список команд и флагов снят с
`tea <команда> --help` установленного бинарника, а не из документации в вебе.
При обновлении `tea` стоит перечитать `--help`: набор флагов между версиями
менялся. Нативные зависимости и правка тел тикетов через `tea api` проверены
живыми запросами: граф блокировок карты #10 в тот день собран заново
(#17 ← #14, #15, #16; #14 ← #12, #13, #18; #16 ← #15).

## Архив

- До 2026-07-26 трекер жил в GitHub Issues (`dementev-dev/…`). Аккаунт
  заблокирован, remote `github` заморожен; все 27 номеров issues воссозданы в
  Gitea один в один. Слепок трекера на момент блокировки —
  `.scratch/backup/20260726-tracker-snapshot.md` (ветка
  `chore/gitea-migration`).
- До 2026-07-19 задачи велись markdown-файлами в `.scratch/<feature>/issues/`
  (фичи `data-generator` и `generator-model-time-startup-history`, задачи
  01–21). Не мигрированы; доступны в истории git — срез `0e312b3`.
