Files
avandClaude Opus 5 cbfae90f3f словарь: пять слов сняты, девять закрыты списком вместо оговорки «прижилось»
Проход упрощения уткнулся в один класс у всех пяти агентов: слово, живущее в
трёх-шести файлах разом. Правка в одном месте развела бы словарь, правка во
всех — уже не упрощение текста скилла. Каждый честно остановился и записал слово
в отчёт, и одни и те же слова всплыли в разных отчётах. Разобрано этим проходом.

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

Список заведён домом язык-словарь в language.md и копией в уставе doc-wording.
Копия обязательна: агент работает в репозитории проекта, где плагина может не
быть, и без списка предъявил бы интейк как англицизм.

Снято пять слов, 29 мест: конфляция → смешение, декорреляция → разведённость,
непоймание → почему не поймали, эвал-сет → проверочный набор, гайд →
руководство. Латинизм или калька при живом русском слове в каждом случае.

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

Непоймание снято ещё и потому, что форма журнала дефектов, которую канон кладёт
в проекты, спрашивает «Почему не поймали», а проза рядом называла это «причиной
непоймания». Скелет и проза о скелете говорили разными словами.

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

Тема 32 в DECISIONS.md, следствия 124-126. Нумерация правил в уставе doc-wording
сдвинута: словарь встал шестым, жаргон и далее уехали на единицу.

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

197 lines
16 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.
# Ведение спринта
Спринт — набор задач под одну цель, замороженный до его конца. Здесь то, что
происходит **внутри** спринта: как задача заканчивается, что считается сделанным,
кто принимает и что идёт в доклад. Как спринт набирается — шаг 4 в
[cadence.md](cadence.md).
## Наблюдаемые исходы задачи
Как они достигаются — дело пайплайна проекта. Сессия знает только исход и его
след.
- **Сделана** — по определению готовности ниже. `close <slug> --implemented`:
файл и строка удаляются, следом остаётся коммит. **Закрывает агент-оркестратор
последним шагом пайплайна, после коммита; приёмка человеком идёт позже и
отменяется `reopen`** — см. «Кто и когда закрывает».
- **Вышла из спринта** — `sprint drop <slug> --reason …`: возвращается в беклог
с вопросом в файле и **без живого незакоммиченного предложения** — иначе при
следующем взятии оно столкнётся с новым. Наработки, которые жалко терять,
переезжают в тело задачи текстом.
- **Оказалась крупнее задачи** — распознаётся **до того, как под неё заведено
предложение об изменении**, иначе его придётся выбрасывать. Выходит из набора,
уходит на декомпозицию; спринт продолжается остальными, части заводятся под той
же целью и в замороженный набор не добавляются.
- **Отменена решением по ходу** — `close <slug> --reason "<ссылка на решение>"`
прямо из спринта. Это редкий, но законный исход, и он называется в докладе.
**Конец спринта** — когда по каждой задаче набора наступил один из исходов. Не
«все сделаны»: иначе одна застрявшая задача держит спринт бесконечно. Затем
`sprint close`.
```mermaid
flowchart TD
take["sprint take — задача в наборе"]
done["сделана<br/>close --implemented"]
out["вышла<br/>sprint drop --reason"]
epic["крупнее задачи<br/>распознаётся до заведения change"]
cancel["отменена решением по ходу<br/>close --reason"]
all{"по каждой задаче набора<br/>наступил исход?"}
harvest["урожай заводится интейком tasks"]
close["sprint close"]
dissolve["sprint close --dissolve --reason<br/>недоделанное — в беклог"]
take --> done
take --> out
take --> epic
take --> cancel
done --> all
out --> all
epic --> all
cancel --> all
all -->|да| harvest
harvest -->|"тег sprint: ставится, пока SPRINT.md не очищен"| close
take -->|"продолжать нечем ни одной задачей — блокер"| dissolve
done -->|"приёмка не сошлась: reopen --reason"| take
```
Два ребра на схеме — те, где порядок обязателен и нарушается молча: **урожай до
`sprint close`** (после команды автотег уже не поставится) и **блокер в обход
исходов** (спринт распускается, а не ждёт).
Схема — **сводка**: определение готовности и правила приёмки ниже, и при
расхождении прав текст.
**Урожай заводится при закрытии спринта, а не при закрытии задачи.** Это
обязанность закрывающего: пройти по спискам находок от исполнителей и завести
недостающее интейком скилла `tasks` — с дедупликацией и картой человеку. Заводимое
метится тегом спринта само (`sprint:<слаг>`), поэтому первая порция следующей
сессии поднимается одной командой `list --tag sprint:<слаг>`. Спринт, закрытый
без этого шага, оставляет находки жить в отчётах — то есть нигде.
**Порядок здесь обязателен: урожай заводится ДО команды `sprint close`.**
Автотег ставится по слагу из `SPRINT.md`, а `sprint close` этот файл очищает;
заведённое после команды остаётся без тега и в первую порцию следующей сессии
не попадёт — молча, потому что пустой `list --tag` выглядит как «урожая не
было». Если так уже вышло, тег ставится руками: `add … --tag sprint:<слаг>`,
слаг берётся из отчёта `sprint close`.
**Провал спринта.** Сработал блокер — спринт распускается (`sprint close
--dissolve --reason …`), недоделанное возвращается в беклог, новый набор
делается после ответа человека. Спринт не «ждёт»: ждать может человек, а
замороженный набор, который нельзя двигать, только мешает.
**Протухший набор — второй законный повод роспуска.** Работа стояла, и человек
вернулся к спринту, состав которого уже не держит в голове. Тем же роспуском:
`sprint close --dissolve --reason "работа стояла с <когда>"`, недоделанное в
беклог, новый набор — после переоценки, а не поверх старого.
Порога в неделях нет и не будет: счётчик простоя пришлось бы вести руками, а
решает всё равно человек. Признак — не срок, а **что набор перестал быть твоим**:
взялся перечитывать, зачем эти задачи вместе, — он протух. Заморозка тут не
мешает, она запрещает *двигать* набор, а не распустить его целиком.
## Определение готовности
Задача засчитывается сделанной, когда верно **всё**:
1. **Пайплайн задачи пройден до конца** — со своим определением готовности, за
которое отвечает проект: проверки, состав ревью, документация, коммит. Здесь
оно не пересказывается и не подменяется — **форма фиксирована, содержание
даёт `CLAUDE.md` проекта**. Пайплайна нет, задача сделана руками — условие
читается как «проверки проекта зелёные и изменение влито».
2. **Критерии приёмки проверены поимённо** — каждый со своим оракулом, исход по
каждому назван. Это единственное, что добавляет управление задачами: пайплайн
отвечает «сделано по правилам», критерии — «сделано то, что заказывали».
3. **Находки по ходу отданы списком** — исполнитель обязан их **назвать**
(каждую, с пометкой «заведена / не заведена: причина»), но **не обязан
заводить**: заведение интерактивно — оно требует дедупликации против беклога
и кладбища, а ещё решений человека. Обязанность **завести урожай** — на
закрытии спринта, ниже. Иначе автономный исполнитель оказался бы разом и
обязан завести задачи, и не вправе сделать это в одиночку.
### Кто и когда закрывает
**Задачу закрывает агент-оркестратор — тот же, кто её и сделал**, последним шагом
пайплайна, после коммита. Порядок:
1. пайплайн доводит задачу до коммита;
2. **после коммита** зовёт `Skill av-dev-pm:tasks` и закрывает задачу
(`close <slug> --implemented`); строка уходит из `SPRINT.md`;
3. **докладывает исход и по каждому критерию — оракул и наблюдаемый исход.**
Это доклад приёмщику, а не отметка «принято».
**Приёмщик и исполнитель здесь совпадают, и это принято сознательно** — цена
названа в `SKILL.md`, раздел «Стимулы». Поэтому закрытие **не окончательно**, а
доклад по критериям — не формальность: он единственное, по чему приёмка вообще
возможна.
**Порядок «коммит, потом закрытие» обязателен.** Закрытие удаляет файл задачи;
упавший коммит после закрытия оставил бы задачу закрытой без единого следа
работы.
**Само закрытие тоже коммитится, отдельным коммитом.** Удаление файла задачи и
правка индекса — правки в рабочем дереве; пока они не в истории, `SPRINT.md`
ничего не показывает, а `reopen` восстанавливает текст из `HEAD` в узком окне:
его закроет первый посторонний коммит. Сообщение про учёт, а не про
работу: `закрыта задача <slug>`.
**Дорога назад существует и обязана быть названа.** Человек на сессии сверил
критерии, и приёмка не сошлась — `tasks.py reopen <slug> --reason "приёмка не
сошлась: …"`:
файл восстанавливается из истории git, строка возвращается в набор идущего
спринта (или в беклог, если спринта нет), строка кладбища снимается. Тело
восстанавливается **на момент удаления** — всё, что было дописано позже, живёт
только в коммите задачи, и это называется в докладе.
### Кто и по чему принимает
Три условия, без которых пункт про критерии не исполняется никем:
1. **Критерии переживают файл задачи.** Файл удаляется при закрытии, поэтому
критерии копируются туда, где их увидит приёмщик. Куда именно — **отвечает
пайплайн проекта, а не слот в `CLAUDE.md`**: он переносит их в `tasks.md`
изменения, когда заводит change. Проект без пайплайна называет своё место
сам.
2. **Принимает человек на сессии, а не отдельный агент.** Исполнитель и приёмщик
в момент закрытия **не разведены** (решение о снятии и его
цена — в `SKILL.md`, «Стимулы»). Опоры остались три: **сохранённый независимый
отчёт ревью** (при конвейере `av-dev-pipeline` — отчёт триажа в
`openspec/changes/archive/<id>/review/`, до архивации — `changes/<id>/review/`),
`SPRINT.md` под git и `reopen`. Переоценка на сессии и есть момент, когда
критерии видит не исполнитель. **Конвейера ревью в проекте нет — первой опоры
нет тоже**, и это называется строкой доклада, а не обходится молча
(`SKILL.md`, «Стимулы»).
3. **Расхождение — дефект критериев.** Приёмщик правит критерии и возвращает
задачу исполнителю **в этом же спринте**: ответ есть, остаток есть, по тесту
про остаток это не выход из спринта.
## Что врывается в замороженный набор
Только два класса — правило и его обоснование в SKILL.md. Здесь механика:
- вторжение **не добавляет** задачу в набор: `SPRINT.md` остаётся набором под
цель. Внеплановая работа делается и называется в докладе отдельной строкой
«внеплановое: что и почему»;
- если внеплановое требует больше пары часов, честнее распустить спринт, чем
делать вид, что набор соблюдается;
- всё остальное падает в беклог через обычный интейк и ждёт сессии.
## Доклад в конце спринта
Проверяемые якоря, а не пересказ:
- **Цель спринта** и по каждой задаче набора: **хеш коммита**, дословный исход
проверок проекта, **исход по каждому критерию приёмки**.
- **Какие развилки решались** и чем обоснованы.
- **Урожай:** сколько задач заведено, какие вопросы накопились, что вышло из
спринта и почему, что было внеплановым.
- **Поимённая сверка урожая** с независимыми отчётами ревью: каждая отложенная
находка имеет либо слаг, либо строку «не заведена: причина». Нулевой урожай при
непустом отчёте — сигнал, а не благополучие. **Отчётов нет** (проект без
конвейера ревью) — сверять не с чем, и строка доклада говорит именно это, а не
«сверено».
- **Созрела ли порция для сессии.** Решение звать — человека, напоминание —
обязанность агента: `⌈урожай / 8⌉` порций.
- **Границы покрытия** сжатой строкой: что в этом спринте не проверялось вовсе.