Files
avandClaude Opus 5 47a2f3de63 язык скиллов av-dev-pm: проход упрощения пятью агентами и разбор находок
Эксперимент: по сабагенту на каждый скилл av-dev-pm, задача — переписать текст
более простыми словами, но только там, где уверен и без потери смысла и
точности. Нормой служил устав языка самого проекта, language.md, включая его
раздел «Порог правки»: правка без нарушенного правила не делается.

36 правок в двенадцати файлах, +64/-63 — почти строго замена, а не
переписывание. Правили залог (пассив с названным деятелем в творительном),
отглагольные существительные, параллельность перечней, канцелярит «является»,
пару garden-path и одно двойное отрицание. Контракт не задет нигде: в диффе нет
изменённых строк-заголовков, а код-спаны встречаются ровно парой минус-плюс,
то есть ни имя, ни флаг, ни путь не переписаны.

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

Шестой агент проверил все 36 правок и нашёл четыре.

Перестановка слов в task-research.md развела формулу с её домом: «число без
источника проход ревью обязан читать как условие» стоит в canon.md и в уставе
doc-consistency, который прямо ссылается на канон как на источник. Откачено —
это ровно тот класс расхождения, который сам doc-consistency и ловит.

«Держит H1, мету и индекс в согласии» — управление требует дополнения, а
language.md в разделе англицизмов прямо оговаривает: русский аналог звучит
коряво — остаётся термин. Взят третий вариант, «согласованными».

В skeletons.md «правка тянет запись, и она называет» — местоимение указывает
на два женских существительных сразу. Стало «и запись называет».

Четвёртая находка не откачена: правка в init/SKILL.md хорошая, но развела
конструкцию с близнецом в canon/SKILL.md — выровнена вторая половина.

Побочно найдена старая логическая инверсия в DECISIONS.md, решение U:
«становится неотличимым, только если отрицание обязательно» — смысл вывернут,
в docs/SKILL.md и во второй записи журнала он правильный. Починено.

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

287 lines
24 KiB
Markdown
Raw Permalink 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` (🎯),
перечисленный в `ROADMAP.md`. Цель постоянна: живёт, пока живёт направление, —
и уходит вместе с ним, если замысел оказался неверен (порядок отмены — в
[tasks](../tasks/references/task-goal.md#отменённая-цель--сперва-задачи-потом-цель)).
- **Задача** — то, что мерджится целиком и даёт видимую пользу.
- **Вопрос** — решение человека. Не останавливает начатую работу, но **блокирует
взятие** задачи в спринт. Живёт внутри файла задачи разделом «Вопросы» и тегом
`question`.
- **Блокер** — состояние, когда спринт не может продолжаться **ни одной**
задачей.
- **Спринт** — набор задач под одну цель, замороженный до его конца.
## Вопрос, блокер, необратимое
| | Что это | Когда спрашиваем | Что останавливает |
| --- | --- | --- | --- |
| **Вопрос** | решение человека | на сессии, пачкой | взятие задачи в спринт |
| **Блокер** | спринт не может продолжаться ни одной задачей | немедленно | всё |
Право на **необратимое** — третье и отдельное: что именно необратимо, называет
`CLAUDE.md` проекта, и спрашивается оно всегда, независимо от спринта.
**Блокер определяется исходом, а не одновременностью.** Встали разом или
высыпались из спринта по одной — если продолжать нечем, это блокер: спринт
распускается (`sprint close --dissolve --reason …`), человек спрашивается
немедленно. Иначе спринт, из которого задачи вышли поштучно, выглядел бы штатно
завершённым, а вопросы тихо ждали бы сессии.
**Отличать вопрос от застревания.** Правило про остаток принадлежит управлению
задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не
исполнения. **Ниже канонический текст; пайплайн проекта на него ссылается, а не
пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются
незаметно, потому что расхождение видно только на редком входе.
> Есть остаток, который доводится без ответа, — задача продолжается, вопрос
> записывается в файл. Остатка нет — задача выходит из спринта.
С двумя оговорками, без которых тест ошибается:
> **Остаток, который материализует нерешённое** — записывает в хранилище,
> журнал, витрину **или наружу** состояние, зависящее от неотвеченного вопроса,
> — **не остаток**. Решение поднимается до начала записи: откатить запись
> дороже, чем подождать ответ, а иногда невозможно. «Наружу» — часть правила, а
> не пример: выкладка, публикация и отправка данных третьей стороне не
> откатываются тем более.
> **Пол для остатка:** остаток, из которого пропала польза, названная в «зачем», —
> это не сделанная задача, а вышедшая из спринта.
## Заморозка набора
**Цель одна.** Набор служит ей; задача, не служащая цели, в спринт не попадает,
даже если взять удобно (`sprint take` это и запрещает). **Задача с открытым
вопросом в набор не берётся.**
**Новая работа падает в беклог, а не в идущий спринт.** Решение «врываться или
отложить» принимается один раз правилом, а не заново каждый раз. Врывается
только два класса:
1. **Необратимый ущерб** — потеря, порча или утечка данных: то, что не чинится
доделкой потом.
2. **Сломан общий станок** — красная проверка, на которой стоит определение
готовности **всех** задач набора. Это не новая работа, а починка того, на чём
делается вся остальная.
Что в проекте считается необратимым ущербом и что — общим станком, называет
`CLAUDE.md` проекта. Не названо — спрашиваем человека, а не решаем сами.
**Конец спринта** — когда каждая задача набора либо сделана, либо вышла с
записанной причиной. Не «все сделаны»: иначе одна застрявшая задача держит
спринт бесконечно. Пустой набор закрывается `sprint close` — скрипт не даст
закрыть непустой.
Ведение спринта целиком — исходы задачи, определение готовности, приёмка,
доклад — [references/sprint.md](references/sprint.md).
## Сессия: четыре шага в этом порядке
Это зависимость, а не список.
1. **Разбор вопросов.**
2. **Разбор прошедшего спринта — про процесс, а не про задачи.** Здесь же оба
судьи документов канона на весь канон разом, раз в спринт: `doc-consistency`
(документы между собой) и `doc-code-drift` (документы против кода).
3. **Переоценка задач** порциями.
4. **Выбор цели и набор спринта.** Цель называет человек, набор собирает агент и
показывает **до старта работ**.
Рёбра подписаны тем, что ломается при их нарушении:
```mermaid
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](references/cadence.md), и при расхождении прав текст.
## Вернулся, а спринт открыт
Сессия — ритуал **между** спринтами, и шаг 1 предполагает только что закрытый.
Вход после перерыва другой, и начинается он не с шага, а с вопроса, свой ли ещё
набор:
1. `tasks.py check` — блок здоровья скажет состояние спринта, число готовых к
взятию и залежавшихся; при расхождении раскладки `--fix`.
2. Прочитать `SPRINT.md`: цель, состав, дата начала.
3. **Развилка, и решает её человек.** Набор всё ещё твой — продолжай спринт, ни
сессии, ни переоценки не нужно, они между спринтами. Взялся перечитывать,
зачем эти задачи собраны вместе, — набор протух:
`sprint close --dissolve --reason …`, недоделанное возвращается в беклог,
дальше обычная сессия с шага 1.
Порога в неделях нет намеренно — почему, в
[references/sprint.md](references/sprint.md), «Протухший набор».
Середины у развилки тоже нет: «доделаю пару штук и решу» — это работа по набору,
которого ты уже не понимаешь.
Процедура каждого шага, размер и отбор порции, храповик на залежавшихся, формат
интерактива и доклад — [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` — каталог задач проекта, по канону всегда `docs/tasks`; `--dir` передаётся
явно каждой командой. Вызов из чужого контекста описан в скилле `tasks`
(«Переносимость»). **Коды выхода** — там же: 1 это дрейф в беклоге, 3 это
«каталога нет», и ветвиться на них надо по-разному.
**Слаг спринта заводит `sprint start`** (по умолчанию — дата) и пишет его в
`SPRINT.md`; всё заведённое **при открытом спринте** помечается `sprint:<слаг>`
автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без
чьей-либо памяти — но ровно до команды `sprint close`, которая `SPRINT.md`
очищает. Отсюда порядок: **урожай заводится до закрытия, слаг для сессии берётся
из отчёта `sprint close`** ([references/sprint.md](references/sprint.md)).
Правки задач делаются мутациями (`edit`, `move`, `close`), а не редактором:
руками правится только тело файла. Это правило скилла `tasks`, здесь оно не
пересказывается.
## Стимулы, которые процесс создаёт
Правило, которое можно обойти в свою пользу, будет обойдено.
**Приёмщик и исполнитель здесь совпадают, и это надо назвать вслух.** Задачу
закрывает и двигает по индексам агент-оркестратор — тот же, кто её и сделал.
Прежде границу держала механика: моста между плагинами не было, и закрыть задачу
пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже —
**только текстовая**. Опоры, которые остались настоящими:
- **независимый отчёт ревью** — артефакт, написанный не исполнителем; по нему
сверяют состав прогона и урожай. Где он лежит, знает пайплайн проекта; при
конвейере `av-dev-pipeline` это отчёт триажа в
`openspec/changes/archive/<id>/review/` (до архивации — `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` (сессия зовёт его операции). Не решает
за человека, какая цель следующая. Не двигает набор идущего спринта.