добавлены плагины av-dev-tasks и av-dev-pipeline

Пара плагинов с намеренно проведённой границей: av-dev-tasks отвечает
за то, что делаем и в каком порядке, av-dev-pipeline — за то, как ведём
одну задачу. Зависимости между ними нет: управление задачами работает и
с ручным исполнением, пайплайн — на проекте с любым учётом задач.

- av-dev-tasks — преемник av-dev-backlog: цели вместо приоритетов,
  спринт под одну цель с заморозкой набора, различение вопроса и
  блокера, каденция «вопросы — разбор — переоценка — набор».
  Раскладка docs/tasks с items/, PLAN.md, BACKLOG.md, SPRINT.md,
  REJECTED.md; проверенное из av-dev-backlog перенесено, не переписано.
- av-dev-pipeline — вынос того, что лежало копиями в healthlog и
  jellybit (3628 строк) и уже разошлось: цикл SDD, конвейер ревью с
  обязательным триажем, прогон нескольких задач разом. Проектная
  специфика вынесена в файл-бриф, charter'ы несут метод.

Коммит фиксирует состояние на момент ревью: три прохода нашли
блокирующие дефекты (нет шага, заводящего бриф; git rebase на занятой
worktree ветке; sprint drop пишет наполовину) — они чинятся следующими
коммитами. Сохранено как база, от которой видно правки.
This commit is contained in:
av
2026-08-03 11:01:29 +03:00
parent 092d07c15d
commit 9219f4a5cd
29 changed files with 5287 additions and 0 deletions
+236
View File
@@ -0,0 +1,236 @@
---
name: tasks
description: Ведение задач и целей как каталога markdown-файлов (одна запись = один файл в items/ + строка в одном из индексов). Заведение задачи, идеи или цели из диалога, разбор находок аудита/ревью, декомпозиция на независимо полезные части, мозговой штурм идеи, гигиена полей и проверка согласованности индексов. Использовать, когда просят добавить задачу/идею/цель, превратить находки ревью в задачи, разбить задачу, проработать идею, поправить формат или проверить беклог. Ритуал между спринтами — скилл session. Не реализует задачи — этим занимается пайплайн проекта.
---
# Задачи
Задачи — каталог markdown-файлов. Одна запись = один файл `items/<slug>.md` плюс
строка **ровно в одном** индексе. Скилл владеет **форматом и содержимым**:
заводит, редактирует, закрывает, разбирает находки ревью, дробит, штурмует идеи.
Чем он **не** владеет: ритуалом между спринтами (разбор вопросов → разбор
прошедшего спринта → переоценка → выбор цели и набор) — это скилл `session`; и
выполнением задачи — это пайплайн проекта.
## Четыре правила, из которых всё следует
Ситуация не покрыта инструкцией — решай по ним.
1. **Беклог гниёт с той стороны, где его пополняют.** Заведение — самая частая
операция и с худшим отказом: из одного разговора рождается пять файлов, а
переоценка потом разгребает то, чего не надо было заводить. Дедупликация и
фильтр на входе дешевле любой чистки. Заводим только то, что **не делаем
сейчас** и о потере чего пожалеем.
2. **Файл — источник истины, индексы производны.** Разошлись — неправы индексы.
Согласованность механизируема и проверяется командой, а не вниманием: всё,
что ловит `tasks.py check`, не должно попадать ни в чек-лист, ни в промпт.
Единственное исключение намеренное: **в каком индексе лежит задача, знают
индексы** — «в спринте» это свойство спринта, а не файла, поля-состояния нет.
3. **Причина переживает запись.** Выкинутая без причины задача вернётся через
квартал тем же текстом. Реализованная оставляет след в коммите — выкинутая не
оставляет ничего, поэтому у неё есть `REJECTED.md`.
4. **Порядка нет, есть цель.** Ни в секциях, ни списком: «что делать дальше»
отвечает набор спринта, а между спринтами порядок не нужен никому — брать
задачи вне спринта запрещает заморозка. Поэтому нет ни приоритетов, ни
«повысить», ни «встать раньше»: вместо повышения — смена цели или включение
в набор.
## Раскладка
```
<tasks>/ по умолчанию docs/tasks, путь настраивается
items/ задачи и цели файлами, <slug>.md, слаги английские
PLAN.md оглавление целей: линия (упорядоченная) и кусты
BACKLOG.md что можно взять — только задачи, целей здесь нет
SPRINT.md текущий спринт: цель, набор, дата
REJECTED.md ушедшее БЕЗ реализации, с причиной и датой
```
Правило, снимающее путаницу: **`BACKLOG.md` — то, что берут; `PLAN.md` — то,
подо что берут.** Цель в спринт взять нельзя, поэтому в списке берущихся ей не
место.
**Задача живёт в одном индексе за раз.** Взята в спринт — строка переезжает из
`BACKLOG.md` в `SPRINT.md`; вышла — обратно. Файл в `items/` при этом **не
двигается**: он и есть запись, индексы лишь показывают, где она числится.
**У сделанной задачи записи не остаётся** — файл и строка удаляются (`close
--implemented`). Ей хватает коммита и документации проекта; вторая запись была
бы вторым домом для того же факта. Вопрос «что было в спринте N» отвечается
даром: `SPRINT.md` лежит под git, `git log -p <tasks>/SPRINT.md` отдаёт историю
всех наборов без отдельного журнала.
## Цели
**Цель — такой же файл в `items/`, тип `[goal]`**, перечисленный в `PLAN.md`:
либо звено упорядоченной **линии** продукта (с обоснованием порядка прозой),
либо тематический **куст** — цель, в последовательность не встающая («прочность
слияния», «журнал и пересборка»). Без второй части половина целей была бы нигде
не перечислена: находки ревью не служат ничему из линии.
- **Список задач цели выводится, а не хранится.** В теле цели — зачем она и что
считается её завершением; перечня задач там нет. Он был бы третьим индексом и
поехал бы на первой же закрытой задаче, а `check` про него не знает. Связь
однонаправленна: задача несёт тег `goal:<слаг>`, перечень даёт
`tasks.py list --goal <слаг>`.
- **Статус цели выводится.** Цель закрыта, когда у неё не осталось открытых
задач; `[x]`/`[~]` руками не ведутся, а `close` цели с живыми задачами
скрипт запретит. Единственная оговорка: цель без задач неотличима — «ещё не
декомпозирована» или «всё закрыто». Различает пометка «декомпозирована» в
теле, проставляемая при переоценке.
- **`[goal]` и `[epic]` — разные вещи.** Цель **постоянна**: живёт, пока живёт
направление. Эпик **временен**: это задача, которая не мерджится целиком, её
разбирают, и он исчезает. Два срока жизни под одним словом разъезжаются,
поэтому слова два.
## Инструмент (`tasks.py`)
Пусть `tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"`.
```
python3 $tk check # согласованность всех индексов + здоровье, exit 1 при расхождениях
python3 $tk check --fix # + починить безопасный дрейф (секция, заголовок, дубли)
python3 $tk list [--stale] [--section S] [--type T] [--tag T] [--goal S] [--index …] [--questions]
python3 $tk add --slug S --title T [--type goal|idea|epic] [--section S] [--goal G] [--hook H] [--tag a,b]
python3 $tk edit S [--title T] [--hook H] [--type T] [--goal G] [--add-tag a,b] [--rm-tag c]
python3 $tk move S --section S [--reason R] [--after S | --first]
python3 $tk close S --reason R # в REJECTED.md + удалить (ушла без реализации)
python3 $tk close S --implemented # просто удалить (реализована, есть коммит)
python3 $tk sprint start --goal S | take S… | drop S… --reason R | close [--dissolve --reason R]
python3 $tk init [--dir D] [--sections …] [--plan-sections …] [--items …] [--backlog …] …
```
Тип — английское ключевое слово `goal` / `idea` / `epic` / `task` (как и прочие
токены команд); `task` префикса не несёт, остальные кодируются `[goal]`/
`[idea]`/`[epic]` в заголовке. Текст задачи при этом русский.
**Мутации правят файл и индексы заодно** — руками строку индекса или мета-строку
не пиши, зови `add`/`edit`/`move`/`close`/`sprint`. Смена заголовка, хука, типа,
цели и **тегов** — это `edit`: он держит H1, мета-строку и индекс в синхроне.
Снятие тега — `--rm-tag` (после ответа на вопрос снимается `question`), смена
цели — `--goal`, он заменяет прежний `goal:*`. Тело задачи скрипт не трогает:
`add` кладёт заголовок, мета-строку и шаблон с подсказками, тело дописываешь
редактором (пока плейсхолдер на месте, `check` напоминает).
`check` — единственный судья согласованности; что именно он ловит, скажет его
вывод, здесь не пересказываем. Гоняй его **в начале сессии** и **после каждой
правки**, даже если правил мутациями: дрейф мог накопиться раньше. Накопившееся
чини `check --fix` — он детерминированно правит безопасное, а неоднозначное
(ссылка на исчезнувший файл, задача сразу в двух индексах) выносит тебе. Это
идёт строкой доклада.
Формат файла, мета-строки, слага, индексов и `REJECTED.md`
[references/task-format.md](references/task-format.md). Там же тест «готова к
взятию» и требования к критериям приёмки.
## Сценарии
### Завести задачу, идею или цель из диалога
1. **Фильтр.** Делаем прямо сейчас — не заводим. Не пожалеем о потере — не
заводим. Родилось три кандидата — покажи их и спроси, какие заводить: молча
заведённая пачка и есть тот самый отказ из правила 1.
2. **Дедуп.** `list` плюс поиск по слагам, хукам и телам (`grep -ril`),
**включая `REJECTED.md`**. Нашлось среди живых — **дописываем в существующий
файл**, а не заводим соседний. Нашлось в `REJECTED.md` — покажи пользователю
ту строку и что изменилось с момента отказа (`add` предупредит и сам, но
молча заводить нельзя). Две задачи об одном — самая дорогая находка
переоценки.
3. **Тип по тесту готовности** (см. task-format): проходит — задача, не
проходит — идея (`--type idea`), проходит по пользе, но не делается одним
заходом — эпик (`--type epic`, сперва декомпозиция). Направление, а не
работа — цель (`--type goal`).
4. **Цель задачи.** У каждой задачи должен быть `--goal <слаг>`: задача вне цели
не попадёт ни в один спринт. Подходящей цели нет — либо она заводится
(`--type goal` кустом), либо это сигнал, что задача никому не служит и
заводить её не надо. У идеи цели может не быть — она проставляется, когда
идея становится задачей.
5. `add …`, затем допиши тело редактором: одна фраза, критерии приёмки с
оракулами, рамки. Хук отвечает «почему это лежит в беклоге» — состояние,
остаток, боль, — а не пересказывает первый абзац, и пишется **для человека**:
не «канонизация внутри транзакции», а «тело 40 МиБ держит блокировку 5 секунд,
соседние доставки уходят в отказ».
6. `check`.
### Разобрать находки аудита или ревью
Ревью и аудиты — тоже источник задач, но с зеркальной диалогу опасностью: не
пять файлов из одной мысли, а сорок файлов из сорока сырых находок. Защита та
же, что в самом ревью: кластеризация по причине, дедуп против живых и
`REJECTED.md`, находка без свидетельства → идея, а не задача, и карта кластеров
пользователю до создания файлов. Порядок, отображение серьёзности и привязка к
целям — [references/from-review.md](references/from-review.md).
### Декомпозиция и штурм идеи
[references/split.md](references/split.md). Обе операции превращают одну запись в
несколько, и у обеих есть проверяемый тест: части должны **мерджиться порознь** и
**каждая давать видимую пользу**, а у штурма исход «выкинуть» — полноправный.
### Гигиена полей
Правится по ходу любой операции, которая задачи касается (но не «заодно» по
всему беклогу):
- **протухший хук** — задача изменилась, а хук отвечает на старый вопрос;
особенно после ответа на вопрос задачи: «Решено: …» на «почему это лежит в
беклоге» уже не отвечает, хук переписывается;
- **вопрос, застрявший в прозе** — вынимается в раздел «Вопросы» плюс тег
`question` (`edit --add-tag question`), иначе он не виден ни `list
--questions`, ни правилу «задача с открытым вопросом в набор не берётся»;
- **тег, который некому снять** — `question` после ответа снимается `edit
--rm-tag question` вместе с записью ответа в тело;
- **свойство репозитория в рамках** — номер миграции, хеш, версия зависимости:
в лежалой задаче протухает молча и становится ложной рамкой. Снимается;
снимок берётся при постановке, а не при заведении;
- **предписание процесса в теле** — «делать таким-то профилем ревью», «взять
такой-то агент»: это второй дом для правила выбора и путь понизить требования
решением, принятым до проектирования. Снимается.
## Слоты проекта
Скилл не знает ни языка программирования, ни сборки, ни CI, ни трекера — задачи
для него просто каталог markdown. Всё проектное живёт в `CLAUDE.md` проекта, и
**проект обязан дописать туда**:
1. **Путь каталога задач**, если он не `docs/tasks`, и **секции беклога** — по
умолчанию `ядро` / `инфра`; граница между ними режется по существу работы, а
не по её поводу. Имена индексов и подкаталога, если они другие, задаются
`init` и живут в `<tasks>/.tasks.json`.
2. **Что такое «сделана»** — чем задача выполняется (пайплайн проекта) и что
входит в его определение готовности. Скилл требует лишь **форму**: пайплайн
проекта пройден + критерии приёмки проверены поимённо.
3. **Куда переезжает суть реализованной задачи** — спеки, ADR, архив изменений:
без этого не проверить, что задача закрыта не коммитом, а решением.
4. **Что считается необратимым** и потому спрашивается у человека всегда
(деплой, выкладка наружу, удаление или перезапись данных).
5. **Оракулы, которые в проекте вообще есть** — чем проверяется критерий
приёмки: тест, команда, прогон на реальных данных, глазами по логу.
Ничего из этого скилл не угадывает: не нашёл — спрашивает пользователя, а не
подставляет умолчание.
## Общее для всех сценариев
- **Развилки — пользователю.** Через `AskUserQuestion`, с уже сформулированным
предварительным суждением (**рекомендация — первым вариантом**). Что выкинуть,
под какую цель отнести, какая рамка идеи верна — решение пользователя. Слаг,
формулировка, порядок строк в индексе — механика, делаем сами.
- **Не больше трёх вопросов за раз.** Пачка длиннее трёх тяжела для ответа;
решений больше — веди **несколько итераций** диалога по ≤3, а не один
перегруженный запрос. Между итерациями применяй уже решённое.
- **Границы покрытия в отчёте.** Любая сессия разбора, штурма или интейка
заканчивается строкой «просмотрено N из M, не трогали — …». Отчёт без неё
сообщает «беклог разобран», не сообщая, какая его часть осталась нетронутой.
- **Ничего не удаляем молча.** Файл исчезает только через `close` — `--reason`
(ушла без реализации) или `--implemented` (реализована). Прямого `rm` нет.
- **Слаги английские**, kebab-case, не транслит: `tie-break-equal-completeness`,
а не `taj-brejk-pri-ravnoj-polnote`. Заголовки, тела и хуки — русские.
## Чего этот скилл не делает
Не пишет код, не заводит спеки и предложения об изменении, не берёт задачу в
работу — этим занимается пайплайн проекта. Не ведёт спринт и не проводит сессию
между спринтами — это `session`. Не решает за пользователя, что важно. Не
переоформляет существующие задачи «заодно»: правится то, чего касается операция.