backlog: переименовать плагин в av-dev-backlog, скилл — в backlog

Соглашение об именах: длинное имя плагина с префиксом av-dev- (уникально в
маркетплейсе), короткие имена скилов внутри. Вызов — /av-dev-backlog:backlog,
единообразно для будущих плагинов.

Путь к backlog.py в SKILL.md обновлён под новую раскладку
($CLAUDE_PLUGIN_ROOT/skills/backlog/scripts/backlog.py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-24 08:52:16 +03:00
co-authored by Claude Opus 4.8
parent a22a825c40
commit 074c6f3448
9 changed files with 15 additions and 11 deletions
@@ -0,0 +1,101 @@
# Груминг беклога
Цель — выкинуть то, что перестало быть задачей, и вернуть остальному честное
состояние. Не «пересмотреть всё», а «пересмотреть порцию до конца».
## Порция и правило остановки
Тридцать задач за один заход — это усталость и штамповка: последние десять
получат «оставить» не потому, что живы, а потому, что сессия затянулась.
- **5–8 задач за сессию.** Больше — только если пользователь настаивает, и тогда
разбей на явные порции с промежуточным докладом.
- **Отбор порции** — один из:
- `backlog.py list --stale` — самые залежавшиеся по дате последней правки в
git; поле «дата касания» заводить не надо, git её уже хранит;
- одна секция приоритета целиком;
- один тег (`--tag`) — например, задачи, пришедшие из одного ревью;
- список от пользователя.
- **Останавливайся на границе порции**, даже если «ещё чуть-чуть осталось».
## Что делать с каждой задачей
Сперва то, что не требует ничьего решения:
1. **Проверь, не сделано ли уже.** Задача, реализованная попутно в соседнем
изменении, — самая частая находка груминга. Смотри код, спеки, историю
коммитов по ключевым словам задачи. Удаление задачи «как реализованной» —
деструктивно и без следа (кладбище для реализованных не пишется), поэтому
порог улики жёсткий: удаляем (`close <slug> --implemented`), только имея
**конкретный коммит или строку спеки**, закрывающие задачу, и ссылка на них
идёт в доклад. Есть лишь косвенные признаки — не удаляй сам, вынеси в пачку
вопросов. Сделана частично → задача сжимается до остатка: тело правишь
редактором, заголовок и хук — через `edit <slug> --title … --hook …`.
2. **Проверь, не отменена ли решением.** ADR, спека или архивный change мог
закрыть вопрос иначе. Тогда `close <slug> --reason "<ссылка на решение>"`.
3. **Проверь пересечения внутри порции.** Две задачи об одном — содержимое в
одну, вторую `close <slug> --reason "слита с <другой-slug>"`.
Затем — то, что решает пользователь:
4. **Жива ли она вообще.** Контекст мог измениться: ушла зависимость, отпал
сценарий, обошли иначе. Здесь и звучит вопрос о выкидывании.
5. **Тот ли приоритет** (тест и правила — в SKILL.md и task-format.md).
6. **Задача ли это по-прежнему.** Не проходит тест «готова к взятию» → `edit
<slug> --type idea`, и её дальнейшая судьба — штурм, а не приоритизация.
Разрослась → `edit <slug> --type epic`, дальше декомпозиция.
## Храповик
Сильно залежавшаяся задача — сигнал сама по себе: её либо ни разу не собирались
делать, либо нечем взять. Измеряй наблюдаемым — датой последней правки из git
(`backlog.py list --stale` ставит такие первыми); счётчик «сколько грумингов
пережила» нигде не хранится, поэтому на него не опирайся.
Задача из верхних строк `--stale`, которую и этот заход оставляет без изменений,
**либо двигается (вверх или на кладбище), либо остаётся с явно записанной
причиной**, почему её держим (`move <slug> --priority <тот же> --reason …`).
Молчаливое «оставить как есть» на давно неподвижной задаче — это решение не
принимать решение; запись причины превращает его в осознанное и не даёт тому же
вопросу всплыть на следующем груминге. В примере ниже вариант «оставить» именно
такой — с названной причиной, а не по умолчанию.
## Интерактив
- Вопросы — через `AskUserQuestion`, **не больше трёх за раз**. Порция в 5–8
задач обычно даёт больше трёх суждений — тогда веди несколько итераций по ≤3, а
не по одному на задачу и не одним перегруженным запросом.
- К каждому варианту — **предварительное суждение**, рекомендация первым
вариантом: «предлагаю выкинуть, потому что …». Пользователю дешевле возразить,
чем судить с нуля.
- Всё, что решается фактом (сделано / отменено / дублируется), решай сам и
показывай списком в докладе, а не выноси в вопросы.
Пример одной итерации — три залежавшихся задачи, механику по ним уже разобрали:
> **Груминг: 3 залежавшихся (порция по `--stale`)**
>
> 1. `versii-kachestvo-repaki` — репаки, апгрейд 1080p→2160p
> - Выкинуть на кладбище *(рекомендую)* — помечена «не боль», за полгода ни разу не возникла
> - Оставить в низком
> - Поднять в средний
> 2. `backup-sqlite` — бэкап SQLite
> - Оставить в среднем *(рекомендую)* — не сработала, но риск реальный
> - Поднять в высокий — обгоняет `retention-ochistka-bd`: без бэкапа ретеншн опасен
> - Выкинуть
> 3. `guessit-sputnik` — guessit как сервис-спутник
> - Понизить до `[idea]` *(рекомендую)* — не проходит тест «готова к взятию»
> - Оставить задачей в низком
Каждый вариант несёт причину — ту самую, что уедет в `move --reason` или
`close --reason`. Ответы применяй сразу и, если в порции осталось ещё, следующей
итерацией показывай следующие ≤3.
## Доклад
- Что просмотрено: N из M, по какому признаку отобрана порция.
- Изменения списком: удалено (реализовано), на кладбище (с причинами), понижено
до идей, слито, переприоритизировано.
- **Границы покрытия**: сколько задач не трогали и какие именно секции или теги
остались — иначе доклад читается как «беклог разобран».
- `backlog.py check` после правок; результат — строкой в докладе.