Files
dev-skills/av-dev-pm/skills/session/SKILL.md
T
av 68218208b7 починены находки финальной сверки: закрытие задачи переехало за коммит
- sprint.md прямо запрещал шаг, который пайплайн теперь делает: раздел «кто и
  когда закрывает» переписан под снятую границу приёмки
- закрытие задачи стало шагом 11, после коммита: раньше упавший коммит оставил
  бы задачу закрытой без следа работы
- контракт close --implemented больше не обещает состоявшуюся приёмку
- слот «куда копируются критерии приёмки» убран из session: на него отвечает
  пайплайн, а канон его не заводил
- research/ в таблице ролей вернул adversary; журнал версий поднимает CLAUDE.md
  целиком, а не тремя пунктами из восьми
- TODO и REMAINING перестали занижать: коммитов одиннадцать, переписок три
2026-08-03 14:48:01 +03:00

226 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: session
description: Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги. Формат и содержимое задач — скилл tasks.
---
# Сессия между спринтами
Работа идёт спринтами: **набор задач под одну цель, замороженный до конца
спринта**. Между спринтами — одна сессия из четырёх шагов. Этот скилл владеет
**ритуалом**: как сессия проводится и как спринт ведётся. Форматом и содержимым
задач владеет скилл `tasks`, выполнением задачи — пайплайн проекта.
## Почему не Scrum
Терминология близка — спринт, груминг, определение готовности, ретроспектива, —
и это удобно: не нужно изобретать слова. Но добрая половина Scrum существует
ради синхронизации людей, которых здесь нет.
**Не берём:** тайм-бокс (спринт ограничен объёмом, а не временем), velocity и
оценки в очках, ежедневный стендап (стендап — это и есть диалог), планирование
отдельно от груминга (владелец беклога один), роль скрам-мастера.
**Берём:** цель спринта, заморозку набора, определение готовности, груминг —
каждое потому, что снимает решение, которое иначе принимается заново каждый раз.
**Ретроспективу берём содержанием, но не отдельным ритуалом:** она шаг той же
сессии. Процесс личный, синхронизировать некого, а отдельная встреча ради трёх
вопросов — та самая плата ритуалом без выгоды.
## Роли
**Человек** выбирает цель спринта, разбирает вопросы, держит право на
необратимое и на истину в самих данных.
**Агент — оркестрация.** Он собирает набор под названную цель, ставит задачи,
принимает отчёты и докладывает. Кто именно делает задачу — исполнитель, сабагент,
пайплайн — дело проекта; сессия про это не знает и знать не должна.
## Единицы
- **Цель** — то, ради чего набирается спринт. Файл `[goal]`, перечисленный в
`PLAN.md`. Цель постоянна: живёт, пока живёт направление.
- **Задача** — то, что мерджится целиком и даёт видимую пользу.
- **Вопрос** — решение человека. Не останавливает начатую работу, но **блокирует
взятие** задачи в спринт. Живёт внутри файла задачи разделом «Вопросы» и тегом
`question`.
- **Блокер** — состояние, когда спринт не может продолжаться **ни одной**
задачей.
- **Спринт** — набор задач под одну цель, замороженный до его конца.
## Вопрос, блокер, необратимое
| | Что это | Когда спрашиваем | Что останавливает |
| --- | --- | --- | --- |
| **Вопрос** | решение человека | на сессии, пачкой | взятие задачи в спринт |
| **Блокер** | спринт не может продолжаться ни одной задачей | немедленно | всё |
Право на **необратимое** — третье и отдельное: что именно необратимо, называет
`CLAUDE.md` проекта, и спрашивается оно всегда, независимо от спринта.
**Блокер определяется исходом, а не одновременностью.** Встали разом или
высыпались из спринта по одной — если продолжать нечем, это блокер: спринт
распускается (`sprint close --dissolve --reason …`), человек спрашивается
немедленно. Иначе спринт, из которого задачи вышли поштучно, выглядел бы штатно
завершённым, а вопросы тихо ждали бы сессии.
**Отличать вопрос от застревания.** Правило про остаток принадлежит управлению
задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не
исполнения. **Ниже канонический текст; пайплайн проекта на него ссылается, а не
пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются
незаметно, потому что расхождение видно только на редком входе.
> Есть остаток, который доводится без ответа, — задача продолжается, вопрос
> записывается в файл. Остатка нет — задача выходит из спринта.
С двумя оговорками, без которых тест ошибается:
> **Остаток, который материализует нерешённое** — записывает в хранилище,
> журнал, витрину **или наружу** состояние, зависящее от неотвеченного вопроса,
> — **не остаток**. Решение поднимается до начала записи: откатить запись
> дороже, чем подождать ответ, а иногда невозможно. «Наружу» — часть правила, а
> не пример: выкладка, публикация и отправка данных третьей стороне не
> откатываются тем более.
> **Пол для остатка:** остаток, из которого пропала польза, названная в хуке, —
> это не сделанная задача, а вышедшая из спринта.
## Заморозка набора
**Цель одна.** Набор служит ей; задача, не служащая цели, в спринт не попадает,
даже если взять удобно (`sprint take` это и запрещает). **Задача с открытым
вопросом в набор не берётся.**
**Новая работа падает в беклог, а не в идущий спринт.** Решение «врываться или
отложить» принимается один раз правилом, а не заново каждый раз. Врывается
только два класса:
1. **Необратимый ущерб** — потеря, порча или утечка данных: то, что не чинится
доделкой потом.
2. **Сломан общий станок** — красная проверка, на которой стоит определение
готовности **всех** задач набора. Это не новая работа, а починка того, на чём
делается вся остальная.
Что в проекте считается необратимым ущербом и что — общим станком, называет
`CLAUDE.md` проекта. Не названо — спрашиваем человека, а не решаем сами.
**Конец спринта** — когда каждая задача набора либо сделана, либо вышла с
записанной причиной. Не «все сделаны»: иначе одна застрявшая задача держит
спринт бесконечно. Пустой набор закрывается `sprint close` — скрипт не даст
закрыть непустой.
Ведение спринта целиком — исходы задачи, определение готовности, приёмка,
доклад — [references/sprint.md](references/sprint.md).
## Сессия: четыре шага в этом порядке
Это зависимость, а не список.
1. **Разбор вопросов.**
2. **Разбор прошедшего спринта — про процесс, а не про задачи.**
3. **Переоценка задач** порциями.
4. **Выбор цели и набор спринта.** Цель называет человек, набор собирает агент и
показывает **до старта работ**.
Процедура каждого шага, размер и отбор порции, храповик на залежавшихся, формат
интерактива и доклад — [references/cadence.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` — каталог задач проекта; цепочка его разрешения и вызов из чужого контекста
описаны в скилле `tasks` («Переносимость»). **Коды выхода** — там же: 1 это
дрейф в беклоге, 3 это «каталога нет», и ветвиться на них надо по-разному.
**Слаг спринта заводит `sprint start`** (по умолчанию — дата) и пишет его в
`SPRINT.md`; всё заведённое при открытом спринте помечается `sprint:<слаг>`
автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без
чьей-либо памяти.
Правки задач делаются мутациями (`edit`, `move`, `close`), а не редактором:
руками правится только тело файла. Это правило скилла `tasks`, здесь оно не
пересказывается.
## Стимулы, которые процесс создаёт
Правило, которое можно обойти в свою пользу, будет обойдено.
**Приёмщик и исполнитель здесь совпадают, и это надо назвать вслух.** Задачу
закрывает и двигает по индексам агент-оркестратор — тот же, кто её и сделал.
Прежде границу держала механика: моста между плагинами не было, и закрыть задачу
пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже —
**только текстовая**. Опоры, которые остались настоящими:
- **отчёт триажа** в `openspec/changes/<id>/review/` — независимый артефакт,
написанный ревью, а не исполнителем; по нему сверяют состав прогона и урожай;
- **`SPRINT.md` под git** — `git log -p` показывает, что и когда было закрыто;
- **`reopen <слаг> --reason`** — закрытие не окончательно. Приёмка человеком на
сессии его отменяет, и это штатная операция, а не скандал.
Известные обходы:
- **Скрыть блокер** — он останавливает всё и выглядит как провал исполнителя.
Защита: тест про остаток плюс прямая запись, что **объявление блокера
неудачей не считается**.
- **Не записать вопрос** на задаче-кандидате, чтобы не вычеркнуть её из
ближайшего набора. Защита: вопросы кандидатов разбираются на той же сессии
**вне очереди порции**.
- **Занизить критерии приёмки**, раз они пол. Защита ослаблена: правит их тот же,
кто по ним отчитывается. Остаётся требование, что расхождение критериев с
сутью — **дефект критериев, о котором сообщают, а не молча дорабатывают**, и
переоценка на сессии, где критерии видит человек.
- **Сжать задачу до остатка** и отчитаться «сделана». Защита ослаблена там же.
Пол для остатка — польза, названная в хуке; проверяет его человек при приёмке,
и `reopen` — его инструмент.
- **Занизить урожай** — не заводить найденное по ходу. Защита: поимённая сверка
со **сохранённым отчётом триажа**, а не с прозой исполнителя. Каждая
отложенная находка имеет либо слаг, либо строку «не заведена: причина».
Нулевой урожай при непустом отчёте виден сразу.
Стимулы внутри пайплайна задачи (занизить требования к проверке, пропустить
проход) принадлежат ему и защищены там же.
## Слоты проекта
Сессия не знает ни языка, ни сборки, ни CI. Часть проектного отвечает
[канон](../canon/references/canon.md) структурой: разбор процесса (шаг 2) живёт
в `docs/review.md`, оракулы и «чем краснеет безусловно» — в семантике гейта в
`CLAUDE.md`. Остальное проект **дописывает в `CLAUDE.md`**:
1. **Пайплайн задачи** — чем задача выполняется и что входит в его определение
готовности. Сессия требует только форму: пайплайн пройден + критерии приёмки
проверены поимённо.
2. **Общий станок** — какая проверка, покраснев, врывается в замороженный
спринт.
3. **Необратимое** — что спрашивается у человека всегда (тот же слот, что у
скилла `tasks`; дом один).
4. **Ориентир по размеру спринта**, если он замерялся. Умолчание — 5–8 задач, и
это **ориентир, а не закон**.
Слота «куда копируются критерии приёмки» здесь нет намеренно: на него отвечает
**пайплайн проекта**, перенося их в описание изменения при его заведении. Проект
без пайплайна называет своё место сам, в слоте 1.
Числа проекта (сколько задач в спринте, сколько времени на задачу, каков прирост
беклога) — предмет шага 2, а не константы этого скилла.
## Чего этот скилл не делает
Не пишет код и не выполняет задачи. Не заводит и не переоформляет задачи сам по
себе — формат и содержимое ведёт `tasks` (сессия зовёт его операции). Не решает
за человека, какая цель следующая. Не двигает набор идущего спринта.