Files
dev-skills/av-dev-pm/skills/session/SKILL.md
T
avandClaude Opus 5 2d39a77444 ревизия покрытия av-dev-pm: три решения из шести оказались «убрать»
Сабагент в роли продакт-менеджера оценил покрытие жизненного цикла личного
проекта скиллами и агентами av-dev-pm. Скоуп сужен по ходу разбора: деплой и
разбор инцидентов делаются вручную, скиллов под них не заводим — три находки
из восьми сняты этим сразу.

Шаг 2 сессии требовал чисел, которых процесс отказался собирать решением.
cadence.md делал обязанностью пересмотр «ориентира по размеру спринта, прироста
беклога на закрытую задачу, времени на задачу» и «сколько заняли задачи против
ожидания». Данных нет: у записи нет дат заведения, взятия и закрытия, close
удаляет файл, sprint close очищает SPRINT.md. Хуже, «против ожидания» и «время
на задачу» требуют оценки и тайм-бокса, а session/SKILL.md в «Почему не Scrum»
их прямо не берёт — пункт противоречил решению через файл от себя. Числа не
пересматривались ни разу, поэтому выкинуты, а не подперты учётом дат. Осталось
качественное; рядом записано, что замеров нет намеренно, иначе следующий
читатель заведёт их обратно как недостающие. Шаг 3 пункт 9 переименован из
«переоценки по измеренному» в «по пройденному».

doc-consistency переехал с каждого синка на сессию, к doc-code-drift. Агент на
opus звался шагом 9 пайплайна, то есть 5-8 opus-проходов за спринт по документам,
меняющимся на несколько абзацев. Довод сильнее денег: расхождение между двумя
документами по определению требует двух, а на большинстве задач синк правит
один. И пачка, отбираемая работой, не видит того, чего работа не касалась, —
а расхождение живёт ровно там. Это снимает открытый вопрос REMAINING про охват
парного статуса ADR. Цена — потеря привязки находки к задаче, принято сознательно.

Отмена цели получила порядок, но не флаг. close запрещал закрыть цель с живыми
задачами и не говорил, что с ними делать. Теперь: сперва задачи поштучно
(close --reason своей причиной либо edit --goal на другую), потом цель в
REJECTED.md, а не в Готово. Флаг --cascade отвергнут: поштучный разбор — не
церемония, а единственный момент, когда видно, что переживёт цель. Место
процедуры — переоценка на сессии, отмена цели и есть разбор её задач.

У брошенного спринта появился второй законный исход. --dissolve везде был
привязан к блокеру, и вернувшийся к месячному набору не имел законного хода:
двигать нельзя, распускать не по чему. Теперь роспуск объясняется блокером или
тем, что набор протух. Порога в неделях нет — тот же класс, что выкинутые
числа: счётчик простоя пришлось бы вести руками. Признак не срок, а что набор
перестал быть твоим. Плюс точка входа «вернулся, а спринт открыт» и триггер в
description скилла.

Журнал канона прогоняется как есть, схлопывать 3 и 4 не стали. Взамен появилась
проверка исхода: шагом 6 adopt и шагом 6 upgrade зовутся оба судьи документов.
Это ответ на открытый вопрос «как проверять, что канон не разошёлся с проектами
после upgrade»: check сверяет число в .pm.json с версией скрипта и про существо
записи не знает ничего, а записи применяются руками.

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

Тема 31 в DECISIONS.md, следствия 117-123.

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

24 KiB
Raw Blame History

name, description
name description
session Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое задач — скилл tasks.

Сессия между спринтами

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

Почему не Scrum

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

Не берём: тайм-бокс (спринт ограничен объёмом, а не временем), velocity и оценки в очках, ежедневный стендап (стендап — это и есть диалог), планирование отдельно от груминга (владелец беклога один), роль скрам-мастера.

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

Роли

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

Агент — оркестрация. Он собирает набор под названную цель, ставит задачи, принимает отчёты и докладывает. Кто именно делает задачу — исполнитель, сабагент, пайплайн — дело проекта; сессия про это не знает и знать не должна.

Единицы

  • Цель — то, ради чего набирается спринт. Файл типа goal (🎯), перечисленный в ROADMAP.md. Цель постоянна: живёт, пока живёт направление, — и уходит вместе с ним, если замысел оказался неверен (порядок отмены — в tasks).
  • Задача — то, что мерджится целиком и даёт видимую пользу.
  • Вопрос — решение человека. Не останавливает начатую работу, но блокирует взятие задачи в спринт. Живёт внутри файла задачи разделом «Вопросы» и тегом question.
  • Блокер — состояние, когда спринт не может продолжаться ни одной задачей.
  • Спринт — набор задач под одну цель, замороженный до его конца.

Вопрос, блокер, необратимое

Что это Когда спрашиваем Что останавливает
Вопрос решение человека на сессии, пачкой взятие задачи в спринт
Блокер спринт не может продолжаться ни одной задачей немедленно всё

Право на необратимое — третье и отдельное: что именно необратимо, называет CLAUDE.md проекта, и спрашивается оно всегда, независимо от спринта.

Блокер определяется исходом, а не одновременностью. Встали разом или высыпались из спринта по одной — если продолжать нечем, это блокер: спринт распускается (sprint close --dissolve --reason …), человек спрашивается немедленно. Иначе спринт, из которого задачи вышли поштучно, выглядел бы штатно завершённым, а вопросы тихо ждали бы сессии.

Отличать вопрос от застревания. Правило про остаток принадлежит управлению задачами: оно решает, сделана задача или вышла, а это исход планирования, не исполнения. Ниже канонический текст; пайплайн проекта на него ссылается, а не пересказывает — два экземпляра одного правила разъезжаются, и разъезжаются незаметно, потому что расхождение видно только на редком входе.

Есть остаток, который доводится без ответа, — задача продолжается, вопрос записывается в файл. Остатка нет — задача выходит из спринта.

С двумя оговорками, без которых тест ошибается:

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

Пол для остатка: остаток, из которого пропала польза, названная в «зачем», — это не сделанная задача, а вышедшая из спринта.

Заморозка набора

Цель одна. Набор служит ей; задача, не служащая цели, в спринт не попадает, даже если взять удобно (sprint take это и запрещает). Задача с открытым вопросом в набор не берётся.

Новая работа падает в беклог, а не в идущий спринт. Решение «врываться или отложить» принимается один раз правилом, а не заново каждый раз. Врывается только два класса:

  1. Необратимый ущерб — потеря, порча или утечка данных: то, что не чинится доделкой потом.
  2. Сломан общий станок — красная проверка, на которой стоит определение готовности всех задач набора. Это не новая работа, а починка того, на чём делается вся остальная.

Что в проекте считается необратимым ущербом и что — общим станком, называет CLAUDE.md проекта. Не названо — спрашиваем человека, а не решаем сами.

Конец спринта — когда каждая задача набора либо сделана, либо вышла с записанной причиной. Не «все сделаны»: иначе одна застрявшая задача держит спринт бесконечно. Пустой набор закрывается sprint close — скрипт не даст закрыть непустой.

Ведение спринта целиком — исходы задачи, определение готовности, приёмка, доклад — references/sprint.md.

Сессия: четыре шага в этом порядке

Это зависимость, а не список.

  1. Разбор вопросов.
  2. Разбор прошедшего спринта — про процесс, а не про задачи. Здесь же оба судьи документов канона на весь канон разом, раз в спринт: doc-consistency (документы между собой) и doc-code-drift (документы против кода).
  3. Переоценка задач порциями.
  4. Выбор цели и набор спринта. Цель называет человек, набор собирает агент и показывает до старта работ.

Рёбра подписаны тем, что ломается при их нарушении:

flowchart TD
    check["tasks.py check (+ --fix)<br/>результат — строкой в доклад"]
    s1["1. Разбор вопросов<br/>пачкой, не больше трёх за раз"]
    s2["2. Разбор прошедшего спринта<br/>про процесс → docs/review.md"]
    s3["3. Переоценка задач порциями"]
    s4["4. Цель называет человек,<br/>набор собирает агент"]
    sprint["спринт: набор заморожен"]

    check --> s1
    s1 --> s2
    s2 --> s3
    s1 -->|"неотвеченный вопрос → переоценка вслепую"| s3
    s3 -->|"без переоценки набор берётся из протухшего"| s4
    s4 --> sprint

Схема — сводка: процедура каждого шага в references/cadence.md, и при расхождении прав текст.

Вернулся, а спринт открыт

Сессия — ритуал между спринтами, и шаг 1 предполагает только что закрытый. Вход после перерыва другой, и начинается он не с шага, а с вопроса, свой ли ещё набор:

  1. tasks.py check — блок здоровья скажет состояние спринта, число готовых к взятию и залежавшихся; при расхождении раскладки --fix.
  2. Прочитать SPRINT.md: цель, состав, дата начала.
  3. Развилка, и решает её человек. Набор всё ещё твой — продолжай спринт, ни сессии, ни переоценки не нужно, они между спринтами. Перечитываешь, зачем эти задачи собраны вместе, — набор протух: sprint close --dissolve --reason …, недоделанное возвращается в беклог, дальше обычная сессия с шага 1.

Порога в неделях нет намеренно — почему, в references/sprint.md, «Протухший набор». Середины у развилки тоже нет: «доделаю пару штук и решу» — это работа по набору, которого ты уже не понимаешь.

Процедура каждого шага, размер и отбор порции, храповик на залежавшихся, формат интерактива и доклад — references/cadence.md.

Инструмент

Тот же tasks.py, что у скилла tasks — оба скилла в одном плагине, путь общий: tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py". Сессии нужны прежде всего:

python3 $tk check --dir D                       # с этого начинается любая сессия
python3 $tk list --dir D --questions            # шаг 1: что накопилось
python3 $tk list --dir D --tag sprint:<слаг>    # шаг 3: урожай спринта, первая порция
python3 $tk list --dir D --stale                # шаг 3: дальше по залежалости
python3 $tk list --dir D --goal <слаг>          # шаг 4: кандидаты под названную цель
python3 $tk sprint start --dir D --goal <слаг>  # шаг 4: заводит и слаг спринта
python3 $tk sprint take --dir D <слаг> …        # шаг 4: набор
python3 $tk sprint close --dir D                # конец спринта; --dissolve при блокере
python3 $tk reopen <слаг> --dir D --reason …    # приёмка не сошлась после закрытия

D — каталог задач проекта, по канону всегда docs/tasks; --dir передаётся явно каждой командой. Вызов из чужого контекста описан в скилле tasks («Переносимость»). Коды выхода — там же: 1 это дрейф в беклоге, 3 это «каталога нет», и ветвиться на них надо по-разному.

Слаг спринта заводит sprint start (по умолчанию — дата) и пишет его в SPRINT.md; всё заведённое при открытом спринте помечается sprint:<слаг> автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без чьей-либо памяти — но ровно до команды sprint close, которая SPRINT.md очищает. Отсюда порядок: урожай заводится до закрытия, слаг для сессии берётся из отчёта sprint close (references/sprint.md).

Правки задач делаются мутациями (edit, move, close), а не редактором: руками правится только тело файла. Это правило скилла tasks, здесь оно не пересказывается.

Стимулы, которые процесс создаёт

Правило, которое можно обойти в свою пользу, будет обойдено.

Приёмщик и исполнитель здесь совпадают, и это надо назвать вслух. Задачу закрывает и двигает по индексам агент-оркестратор — тот же, кто её и сделал. Прежде границу держала механика: моста между плагинами не было, и закрыть задачу пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже — только текстовая. Опоры, которые остались настоящими:

  • независимый отчёт ревью — артефакт, написанный не исполнителем; по нему сверяют состав прогона и урожай. Где он лежит, знает пайплайн проекта; при конвейере av-dev-pipeline это отчёт триажа в openspec/changes/archive/<id>/review/ (до архивации — changes/<id>/review/);
  • SPRINT.md под gitgit log -p показывает, что и когда было закрыто. Работает, только если закрытие закоммичено: удаление файла задачи и правка индекса, оставшиеся в рабочем дереве, никакой истории не образуют;
  • reopen <слаг> --reason — закрытие не окончательно. Приёмка человеком на сессии его отменяет, и это штатная операция, а не скандал.

Известные обходы:

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

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

Стимулы внутри пайплайна задачи (занизить требования к проверке, пропустить проход) принадлежат ему и защищены там же.

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

Сессия не знает ни языка, ни сборки, ни CI. Часть проектного отвечает канон структурой: разбор процесса (шаг 2) живёт в docs/review.md, оракулы и «чем краснеет безусловно» — в семантике гейта в CLAUDE.md. Остальное проект дописывает в CLAUDE.md:

  1. Пайплайн задачи — чем задача выполняется и что входит в его определение готовности. Сессия требует только форму: пайплайн пройден + критерии приёмки проверены поимённо.
  2. Общий станок — какая проверка, покраснев, врывается в замороженный спринт.
  3. Необратимое — что спрашивается у человека всегда (тот же слот, что у скилла tasks; дом один).
  4. Ориентир по размеру спринта, если он замерялся. Умолчание — 5–8 задач, и это ориентир, а не закон.

Слота «куда копируются критерии приёмки» здесь нет намеренно: на него отвечает пайплайн проекта, перенося их в описание изменения при его заведении. Проект без пайплайна называет своё место сам, в слоте 1.

Числа проекта (сколько задач в спринте, сколько времени на задачу, каков прирост беклога) — предмет шага 2, а не константы этого скилла.

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

Не пишет код и не выполняет задачи. Не заводит и не переоформляет задачи сам по себе — формат и содержимое ведёт tasks (сессия зовёт его операции). Не решает за человека, какая цель следующая. Не двигает набор идущего спринта.