Files
dev-skills/av-dev-pm/skills/tasks/SKILL.md
T
avandClaude Opus 5 cc173b6b94 ступень ревью поднимает проход, а не риск
Полный набор гонялся чаще, чем оправдано, и размер задач тут вторая причина,
не первая. Первая — триггеры: миграция схемы, публичный контракт и инвариант
поднимали ступень, не добавляя ни одного прохода. Миграцию гоняет gate шагом
миграций и разбирает ops, контракт сверяет specs направлением code→spec,
инвариант даёт основание для critical любому проходу — все трое уже в
standard. На проекте с базой и эндпоинтами верхняя ступень оказывалась не
исключением, а умолчанием: правило объявляло исключением то, что происходит
всегда.

Теперь ступень поднимает то, что даёт работу новому проходу. wide означает
ровно одно — изменение вводит новое понятие или структурную единицу; добавить
поле в существующий ответ это не концепт. standard стал рабочим умолчанием.
Проект, где изменение контракта и правда архитектурное, поднимает его сам в
docs/review.md — уточнением, а не возвратом прежнего умолчания.

Чекпоинт design получил то же условие: specs идёт всегда, rubric и
architecture — только при новом понятии. Он стоит на каждой задаче, поэтому
при мелкой нарезке три прохода умножаются на число задач.

Со стороны задач — шов нарезки: тест декомпозиции отвечает, допустим ли
разрез, шов отвечает, где его провести. Резать по границе, за которой падает
ступень; не резать, когда обе половины остаются в одной — костяк из четырёх
проходов платится за каждую задачу, и такой разрез делает ревью дороже.
Порога в числе границ нет по тому же принципу, что в теме 16: размер не
триггер. Дешёвое место заметить разнородную задачу — показ набора спринта,
там «Затрагивает» уже написан, а предложение ещё не заведено.

Правило выведено из состава проходов, а не из статистики прогонов — замер
остаётся за обкаткой. DECISIONS 18, RRR–WWW и следствия 72–75; JJJ темы 17
помечен как пересмотренный. Шаг про «Триггеры профиля» дописан в ещё не
выкаченную версию 3 канона, а не отдельной версией.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 17:06:12 +03:00

42 KiB
Raw Blame History

name, description
name description
tasks Ведение задач и целей как каталога markdown-файлов (одна запись = один файл в items/ + строка в одном из индексов). Заведение задачи, идеи или цели из диалога, разбор находок аудита/ревью, декомпозиция на независимо полезные части, мозговой штурм идеи, гигиена полей и проверка согласованности индексов. Использовать, когда просят добавить задачу/идею/цель, превратить находки ревью в задачи, разбить задачу, проработать идею, поправить формат или проверить беклог. Ритуал между спринтами — скилл session. Не реализует задачи — этим занимается пайплайн проекта.

Задачи

Задачи — каталог markdown-файлов. Одна запись = один файл items/<slug>.md плюс строка ровно в одном индексе. Скилл владеет форматом и содержимым: заводит, редактирует, закрывает, разбирает находки ревью, дробит, штурмует идеи.

Чем он не владеет: ритуалом между спринтами (разбор вопросов → разбор прошедшего спринта → переоценка → выбор цели и набор) — это скилл session; и выполнением задачи — это пайплайн проекта.

Четыре правила, из которых всё следует

Ситуация не покрыта инструкцией — решай по ним.

  1. Беклог гниёт с той стороны, где его пополняют. Заведение — самая частая операция и с худшим отказом: из одного разговора рождается пять файлов, а переоценка потом разгребает то, чего не надо было заводить. Дедупликация и фильтр на входе дешевле любой чистки. Заводим только то, что не делаем сейчас и о потере чего пожалеем.
  2. Файл — источник истины, индексы производны. Разошлись — неправы индексы. Согласованность механизируема и проверяется командой, а не вниманием: всё, что ловит tasks.py check, не должно попадать ни в чек-лист, ни в промпт. Поэтому «зачем» живёт в мете файла, а строка индекса его лишь повторяет: пока поле лежало только в индексе, восстановление пропавшей строки теряло его молча и навсегда. Единственное исключение намеренное: в каком индексе лежит задача, знают индексы — «в спринте» это свойство спринта, а не файла, поля-состояния нет.
  3. Причина переживает запись. Выкинутая без причины задача вернётся через квартал тем же текстом. Реализованная оставляет след в коммите — выкинутая не оставляет ничего, поэтому у неё есть REJECTED.md.
  4. Порядка нет, есть цель. Ни в секциях, ни списком: «что делать дальше» отвечает набор спринта, а между спринтами порядок не нужен никому — брать задачи вне спринта запрещает заморозка. Поэтому нет ни приоритетов, ни «повысить», ни «встать раньше»: вместо повышения — смена цели или включение в набор.

Раскладка

Каталог задач — docs/tasks, жёстко: это часть канона документов, и подгоняется под него проект, а не наоборот.

docs/tasks/
  items/            задачи и цели файлами, <slug>.md, слаги английские
  ROADMAP.md        оглавление целей: порядок (значим) и темы (без порядка)
  BACKLOG.md        что можно взять — только задачи, целей здесь нет
  SPRINT.md         текущий спринт: цель, набор, дата
  REJECTED.md       ушедшее БЕЗ реализации, с причиной и датой

Правило, снимающее путаницу: BACKLOG.md — то, что берут; ROADMAP.md — то, подо что берут. Цель в спринт взять нельзя, поэтому в списке берущихся ей не место.

Секции «блокеры» в беклоге нет. Блокер — это состояние (спринт не может продолжаться ни одной задачей), а не полка: он живёт ровно до ответа человека, и записи в такой секции не успевают жить. Следы блокера остаются вопросами в файлах задач распущенного спринта. Постоянно пустая секция со старой семантикой «разбираются пачками» противоречила бы правилу «блокер эскалируется немедленно», поэтому init её заводить отказывается, а check о ней говорит. Проекту, который переезжает с такой секцией, её надо удалить — это единственное место, где это сказано.

Задача живёт в одном индексе за раз. Взята в спринт — строка переезжает из BACKLOG.md в SPRINT.md; вышла — обратно. Файл в items/ при этом не двигается: он и есть запись, индексы лишь показывают, где она числится.

У сделанной задачи записи не остаётся — файл и строка удаляются (close --implemented). Ей хватает коммита и документации проекта; вторая запись была бы вторым домом для того же факта. Вопрос «что было в спринте N» отвечается даром: SPRINT.md лежит под git, git log -p docs/tasks/SPRINT.md отдаёт историю всех наборов без отдельного журнала.

Куда запись может переехать и какой командой — весь набор переходов:

stateDiagram-v2
    state "BACKLOG.md — что берут" as B
    state "ROADMAP.md — подо что берут" as P
    state "SPRINT.md — набор спринта" as S
    state "REJECTED.md — ушла без реализации" as R
    state "записи нет — реализована" as D

    [*] --> B: add
    [*] --> P: add --type goal
    B --> P: edit --type goal --section
    P --> B: edit --type task --section
    B --> S: sprint take
    S --> B: sprint drop --reason
    S --> D: close --implemented
    B --> R: close --reason
    S --> R: close --reason
    D --> B: reopen --reason
    R --> B: reopen --reason

Состояния здесь — где числится строка, а не где лежит файл: файл items/<slug>.md не двигается ни на одном переходе. Стрелок «руками» на схеме нет намеренно — каждый переход это команда, и другого способа его совершить не существует.

Схема — сводка: условия и оговорки живут в тексте разделов, и при расхождении прав текст.

Цели

Цель — такой же файл в items/, тип [goal], перечисленный в ROADMAP.md: либо цель из секции порядок — там очередь значима и обоснована прозой, — либо тематическая, в порядок не встающая («прочность слияния», «журнал и пересборка»). Без второй секции половина целей была бы нигде не перечислена: находки ревью не служат ничему из порядка.

  • Список задач цели выводится, а не хранится. В теле цели — зачем она и что считается её завершением; перечня задач там нет. Он был бы третьим индексом и поехал бы на первой же закрытой задаче, а check про него не знает. Связь однонаправленна: задача несёт тег goal:<слаг>, перечень даёт tasks.py list --goal <слаг>.
  • Статус цели выводится. Цель закрыта, когда у неё не осталось открытых задач; [x]/[~] руками не ведутся, а close цели с живыми задачами скрипт запретит. Единственная оговорка: цель без задач неотличима — «ещё не разобрана» или «всё закрыто». Различает тег decomposed в мете цели: он ставится, когда цель разложена на задачи. Тег, а не строка в теле — потому что проверяется механически: check напоминает о нём у пустой цели (замечанием, не ошибкой — неразобранная цель это законное состояние), а check --fix сам проставляет его цели, у которой задачи есть.
  • [goal] и [epic] — разные вещи. Цель постоянна: живёт, пока живёт направление. Эпик временен: это задача, которая не мерджится целиком, её разбирают, и он исчезает. Два срока жизни под одним словом разъезжаются, поэтому слова два.

Род работы

Тип записи и род работы — две оси, и путать их нельзя. Тип отвечает «что это за запись» (цель, идея, эпик, задача), род — «какого рода работа»: feature, fix, chore, research. Одним значением на оба вопроса не ответить: идея бывает про функцию, эпик функцией и является.

  • feature — снаружи появляется или меняется то, чего раньше не было.
  • fix — поведение расходится с заявленным, и расхождение воспроизводится. Не воспроизводится — это research, а не fix.
  • chore — обслуживание: зависимости, сборка, перенос, чистка. Наблюдаемое поведение не меняется, и в этом всё дело: у chore тест готовности слабее честно, а не молча. «Что станет наблюдаемо иначе» здесь отвечается разработчику («перестанет собираться два раза», «уедет последний вызов устаревшего API»), а не пользователю. Пока рода не было, такие задачи либо не заводились, либо формулировались как выдуманная польза.
  • research — исход работы знание, а не изменение системы: ответ на вопрос, замер, разведка. Приёмка — записанный ответ (docs/research/, ADR, тело задачи), а не изменённый код.

Дом рода — тег kind:<род>, а не префикс заголовка и не поле меты: теги здесь единственный механизм разметки, и list --kind fix работает даром. Цена известна: в строку индекса род не попадает (индексы производны), и «в наборе одни починки» видно командой, а не глазами по SPRINT.md.

Словарь закрыт. Открытый разъедется на синонимах — bug, bugfix, fix, defect, — и отбор по роду перестанет отвечать на свой единственный вопрос. Ни один род не подходит — это сигнал, что в задаче их два и её надо разделить.

Род обязателен у задачи, у цели запрещён, у идеи и эпика необязателен — идея получает его, когда становится задачей, а эпик исчезает после разбора, и род несут его части. Требуется он там, где по нему принимают решение: sprint take без рода откажет. check о пропаже только напоминает — беклог, заведённый до появления рода, законен, и переоформлять его «заодно» здесь не просят.

Род не выбирает профиль ревью и вообще ничего не предписывает пайплайну. Профиль выбирается по факту изменения, а не по роду задачи: chore бывает миграцией схемы, fix — правкой публичного контракта. Правило «предписание процесса в теле задачи снимается» родом не отменяется, а подтверждается: он описывает работу, а не то, как её проверять.

Как написана задача

Два требования к тексту, и оба про то, чтобы задачу можно было оценить, не открывая код.

Функции и границы, а не намерения. Задача называет, что система начнёт делать, и какие границы это трогает: эндпоинт или команду, таблицу и миграцию, формат на диске, публичный тип пакета, внешний сервис. Перечень живёт разделом «Затрагивает» (форма — references/task-format.md) и требуется к взятию в спринт. Без него задача оценивается по объёму текста, а не по объёму поверхности, — и оценка систематически занижена ровно там, где текст короткий, а границ много. Названы границы, а не то, как они изменятся: план реализации живёт в предложении об изменении, а не в задаче.

Предметно, но без усложнения. Текст задачи читает человек, который решает, брать её или нет, и делает это по строке индекса и одному экрану тела.

  • англицизм, у которого есть русское слово, — заменяется: не «зафиксить флоу», а «починить порядок доставки»; не «отрефакторить», а «убрать второй путь приёма». Английские остаются там, где они и есть имя вещи: слаг, capability, имя пакета, команда, тип в коде.
  • термин, которого нет в паспорте, архитектуре или конвенциях проекта, вводится одной строкой или не употребляется. Свой словарь у задачи — самый дешёвый способ сделать беклог нечитаемым для того, кто вернётся к нему через квартал.
  • сложность формулировки — не признак сложности работы. Задачу, которую не удаётся сказать просто, чаще всего не удаётся и оценить: это либо две задачи, либо идея.

Эти правила — про язык, а не про объём: короткая задача без границ хуже длинной с ними.

Инструмент (tasks.py)

Пусть tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py", а Ddocs/tasks от корня проекта. --dir стоит в примерах намеренно: вызов из подкаталога — обычное дело.

python3 $tk check --dir D                # согласованность индексов + здоровье
python3 $tk check --dir D --fix          # + починить дрейф (секция, заголовок, дубли, «зачем», форма меты)
python3 $tk list --dir D [--stale] [--section S] [--type T] [--kind K] [--tag a,b] [--goal S] [--index …] [--questions]
python3 $tk add --dir D --slug S --title T [--type goal|idea|epic] [--section S] [--goal G] [--kind K] [--why «зачем»] [--tag a,b]
python3 $tk edit S --dir D [--title T] [--why «зачем»] [--type T] [--goal G] [--kind K] [--add-tag a,b] [--rm-tag c]
python3 $tk move S --dir D --section S [--reason R] [--after S | --first]
python3 $tk close S --dir D --reason R      # в REJECTED.md + удалить (ушла без реализации)
python3 $tk close S --dir D --implemented   # просто удалить (реализована и закоммичена)
python3 $tk reopen S --dir D --reason R     # вернуть закрытую: приёмка не сошлась
python3 $tk sprint start --goal S --dir D | take S… | drop S… --reason R | close [--dissolve --reason R]
python3 $tk init --dir D [--sections …] [--roadmap-sections …] [--items …] [--backlog …] …
python3 $tk adopt scan --from … | apply --plan …   # разовая адаптация, references/adopt.md

Коды выхода — единый словарь; на нём ветвятся скиллы, а не на тексте вывода:

Код Что случилось Что делать
0 сошлось / сделано дальше по сценарию
1 только check: найден дрейф индексов и файлов check --fix, остаток разобрать
2 ошибка употребления: аргументы или нарушенное правило читать сообщение, это отказ по существу
3 окружение: каталог не найден, конфиг битый или мимо диска чинится путём или docs/.pm.json, повтор не поможет
4 внутренний сбой дефект скрипта, доложить

Различать 1 и 3 обязательно: «дрейф в беклоге» — рабочая ситуация, «каталога нет» — нерабочая, и одинаковая реакция на них была бы неверна в обоих случаях.

Тип — английское ключевое слово goal / idea / epic / task (как и прочие токены команд); task префикса не несёт, остальные кодируются [goal]/ [idea]/[epic] в заголовке. Текст задачи при этом русский.

Мутации правят файл и индексы заодно — руками строку индекса или мету не пиши, зови add/edit/move/close/sprint. Смена заголовка, «зачем», типа, цели, рода работы и тегов — это edit: он держит H1, мету и индекс в синхроне. Снятие тега — --rm-tag (после ответа на вопрос снимается question), смена цели — --goal, рода — --kind; оба заменяют прежнее значение, а не добавляют второе.

Переезд между индексами — следствие смены типа, а не отдельная команда. edit <slug> --type goal --section <часть роадмапа> переносит строку из BACKLOG.md в ROADMAP.md (и обратно --type task --section <секция беклога>); move двигает только внутри одного индекса и пишет причину. --section у edit работает только при таком переезде — иначе он отсылает к move, потому что смена секции без причины и есть тот дрейф, который потом никто не объяснит. Задача в наборе спринта тип не меняет вовсе: сперва sprint drop.

Тело задачи скрипт не трогает: add кладёт заголовок, мета-блок и шаблон с подсказками, тело дописываешь редактором (пока плейсхолдер на месте, check напоминает).

check — единственный судья согласованности; что именно он ловит, скажет его вывод, здесь не пересказываем. Гоняй его в начале сессии и после каждой правки, даже если правил мутациями: дрейф мог накопиться раньше. Накопившееся чини check --fix — он детерминированно правит то, где истина однозначна (секция, заголовок, дубли, «зачем» из индекса в файл, старая форма меты, пометка decomposed у цели с задачами), а неоднозначное (задача сразу в двух индексах, нечего восстанавливать) печатает отдельной пометкой НЕОДНОЗНАЧНО — это тебе, и это идёт строкой доклада. Ссылка на исчезнувший файл в пометку не попадает: --fix её просто не трогает, и она остаётся ОШИБКА обычного check — то есть видна, но в докладе её надо назвать отдельно.

--fix правит и файлы — ровно в двух местах, где источник ровно один и выбирать не из чего: «зачем», оставшееся только в индексе, переезжает в мету, и цель, у которой есть задачи, получает тег decomposed. Оба случая печатаются поимённо.

Что механизировано, а что нет. У задачи, взятой в набор (sprint take и check по задачам спринта), проверяются три вещи, и у каждой своя глубина:

  • критерии приёмки — число пунктов жёстко (меньше двух отказ, больше пяти замечание), наличие оракула эвристикой по слову «оракул» в пункте;
  • род работы — жёстко: назван и из закрытого словаря;
  • раздел «Затрагивает» — только наличие непустого. Полнота перечня машине не видна: границу, которую забыли назвать, она от отсутствующей не отличает.

Настоящий оракул от слова «оракул» машина тоже не отличает, поэтому эвристика даёт только замечание, и в докладе это называется как есть: «проверено число пунктов и наличие границ, годность оракулов и полнота границ — глазами».

Формат файла, меты, слага, индексов и REJECTED.mdreferences/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. Род работы--kind feature|fix|chore|research (см. «Род работы»). Не подходит ни один — задача не одна, разбирай.
  6. add …, затем допиши тело редактором: одна фраза, затрагиваемые границы, критерии приёмки с оракулами, рамки. «Зачем» отвечает «зачем нужна эта задача» — состояние, остаток, боль, — а не пересказывает первый абзац, и пишется для человека: не «канонизация внутри транзакции», а «тело 40 МиБ держит блокировку 5 секунд, соседние доставки уходят в отказ».
  7. check.

Разобрать находки аудита или ревью

Ревью и аудиты — тоже источник задач, но с зеркальной диалогу опасностью: не пять файлов из одной мысли, а сорок файлов из сорока сырых находок. Защита та же, что в самом ревью: кластеризация по причине, дедуп против живых и REJECTED.md, находка без свидетельства → идея, а не задача, и карта кластеров пользователю до создания файлов. Порядок, отображение серьёзности и привязка к целям — references/from-review.md.

Прийти в репозиторий, где задачи уже как-то ведутся

Разовая операция: вывести каталог задач из старой раскладки беклога, TODO.md, заметок или списка шагов роадмапа — references/adopt.md. Сюда же относится переименование транслитных слагов в английские: оно делается одним проходом вместе с починкой перекрёстных ссылок, а не по одному слагу.

Если переводить надо не только задачи, а весь docs/ — это скилл av-dev-pm:canon, и он зовёт этот сценарий сам на своём шаге.

Декомпозиция и штурм идеи

references/split.md. Обе операции превращают одну запись в несколько, и у обеих есть проверяемый тест: части должны мерджиться порознь и каждая давать видимую пользу, а у штурма исход «выкинуть» — полноправный.

Там же шов: где резать, когда допустимых мест несколько. Коротко — по границе, которая одна поднимает ступень ревью выше остальных; и не резать, когда обе половины остаются в одной ступени, потому что несокращаемый костяк проверок платится за каждую задачу отдельно.

Гигиена полей

Правится по ходу любой операции, которая задачи касается (но не «заодно» по всему беклогу):

  • протухшее «зачем» — задача изменилась, а поле отвечает на старый вопрос; особенно после ответа на вопрос задачи: «Решено: …» на «почему это лежит в беклоге» уже не отвечает. Переписывается edit <slug> --why … — он правит мету файла и строку индекса заодно;
  • вопрос, застрявший в прозе — вынимается в раздел «Вопросы» плюс тег question (edit --add-tag question), иначе он не виден ни list --questions, ни правилу «задача с открытым вопросом в набор не берётся»;
  • тег, который некому снятьquestion после ответа снимается edit --rm-tag question вместе с записью ответа в тело и опустошением раздела «Вопросы»: судит раздел, а не тег (references/task-format.md);
  • свойство репозитория в рамках — номер миграции, хеш, версия зависимости: в лежалой задаче протухает молча и становится ложной рамкой. Снимается; снимок берётся при постановке, а не при заведении;
  • предписание процесса в теле — «делать таким-то профилем ревью», «взять такой-то агент»: это второй дом для правила выбора и путь понизить требования решением, принятым до проектирования. Снимается;
  • род, разошедшийся с задачей — задача заводилась починкой, а после разбора оказалось, что поведение никогда и не было заявлено: это feature, а не fix. Правится edit <slug> --kind …; род, оставшийся от прошлой формулировки, врёт ровно там, где по нему отбирают;
  • границы, названные вместо реализации — «переписать хранилище на новый драйвер» в разделе «Затрагивает» это не граница, а замысел. Границы — таблица points и её миграция, эндпоинт POST /ingest, формат отпечатка на диске. Переписывается перечнем;
  • англицизм и термин из ниоткуда — правится по ходу той же операции, что касается задачи (см. «Как написана задача»). Именно по ходу: беклог не переписывают ради языка.

Переносимость

Скилл независим от языка программирования, сборки, CI и трекера: он ничего не знает ни про Go, ни про npm, ни про конкретный багтрекер — задачи для него просто каталог markdown. Текст задач — русский (язык документации проекта); зашита только латиница слага. OpenSpec ему тоже не нужен.

  • Каталог задач — docs/tasks, жёстко, и --dir передаётся явно всегда: раскладка канона одинакова во всех проектах, и искать больше нечего. Каталога нет — код 3 и вопрос человеку; init заводит его только когда проект действительно новый, а перевод чужой раскладки делает av-dev-pm:canon. У скрипта поиск вверх по дереву ещё жив — он для непереведённых проектов, и полагаться на него скилл не должен: молча найденный чужой каталог это дрейф.
  • Настройки живут в docs/.pm.json, ключ tasks: имена файлов и заголовков, и только если они отличаются от умолчания. Один конфиг на весь канон, а не по одному на каталог. Неизвестный ключ — код 3 на любой команде, так что лишнее слово в этом объекте останавливает работу с задачами целиком.
  • Секции беклога берутся из заголовков ## индекса как есть; их количество и названия — дело проекта (умолчание ядро / инфра). В конфиге их нет — второй список разошёлся бы с заголовками молча.

Вызов из другого плагина

$CLAUDE_PLUGIN_ROOT раскрывается только внутри своего плагина: пайплайн задачи, конвейер ревью и любой другой чужой контекст до tasks.py по этой переменной не дотянутся. Мост — вызов скилла через пространство имён, а не путь:

Чужой контекст зовёт Skill av-dev-pm:tasks и называет, что нужно сделать («закрой задачу <слаг>, реализована»). Скилл разрешает свой $CLAUDE_PLUGIN_ROOT сам. Путь наружу не выносится вовсе.

Плагина в проекте нет — вызов не разрешится, и вызывающий не выдумывает путь и не правит индекс руками, а сообщает в докладе, что учёт задач остаётся за владельцем.

Слоты проекта

Почти всё, что скиллу нужно знать о проекте, отвечает канон структурой: куда переезжает суть реализованной задачи — openspec/specs, adr/, архив change; какие в проекте оракулы — семантика гейта в CLAUDE.md. Отдельными слотами остаётся то, чего из раскладки не вывести. Проект дописывает в CLAUDE.md:

  1. Что такое «сделана» — чем задача выполняется (пайплайн проекта) и что входит в его определение готовности. Скилл требует лишь форму: пайплайн проекта пройден + критерии приёмки проверены поимённо.
  2. Что считается необратимым и потому спрашивается у человека всегда (деплой, выкладка наружу, удаление или перезапись данных).

Ни того ни другого скилл не угадывает: не нашёл — спрашивает пользователя, а не подставляет умолчание.

Общее для всех сценариев

  • Развилки — пользователю. Через AskUserQuestion, с уже сформулированным предварительным суждением (рекомендация — первым вариантом). Что выкинуть, под какую цель отнести, какая рамка идеи верна — решение пользователя. Слаг, формулировка, порядок строк в индексе — механика, делаем сами.
  • Не больше трёх вопросов за раз. Пачка длиннее трёх тяжела для ответа; решений больше — веди несколько итераций диалога по ≤3, а не один перегруженный запрос. Между итерациями применяй уже решённое.
  • Границы покрытия в отчёте. Любая сессия разбора, штурма или интейка заканчивается строкой «просмотрено N из M, не трогали — …». Отчёт без неё сообщает «беклог разобран», не сообщая, какая его часть осталась нетронутой.
  • Ничего не удаляем молча. Файл исчезает только через close--reason (ушла без реализации) или --implemented (реализована). Прямого rm нет.
  • Слаги английские, kebab-case, не транслит: tie-break-equal-completeness, а не taj-brejk-pri-ravnoj-polnote. Заголовки, тела и «зачем» — русские.

Чего этот скилл не делает

Не пишет код, не заводит спеки и предложения об изменении, не берёт задачу в работу — этим занимается пайплайн проекта. Не ведёт спринт и не проводит сессию между спринтами — это session. Не решает за пользователя, что важно. Не переоформляет существующие задачи «заодно»: правится то, чего касается операция.