ревью двумя проходами: 20 находок, все починены
Два независимых сабагента на av-dev-pm и av-dev-pipeline. Две находки нашли оба. Главная — моя же перестановка закрытия за коммит сломала reopen и батч. close печатал «дорога назад из git», а reopen искал коммит удаления, которого в новом порядке ещё нет: шаг 11 последний, учёт остаётся незакоммиченным. Проверено прогоном — отказ кодом 2 на свежезакрытой задаче. Тем же грязным деревом ломались rebase и worktree remove в батче: каждая закрывшая задачу ветка уехала бы в провалившиеся. Починено с обеих сторон: reopen берёт текст из HEAD, если коммита удаления нет, а шаг 11 коммитит учёт вторым коммитом. Вторая — канонический пример docs/.pm.json убивал tasks.py. Четыре документа показывали ключ tasks.sections, которого скрипт не знает: неизвестный ключ это код 3 на любой команде. Проект, заведённый по канону дословно, остался бы без работы с задачами, а docs.py при этом печатал «канон соблюдён». Секции живут в заголовках индекса и второго дома не получают. Остальные восемнадцать: init писал конфиг в упразднённый .tasks.json; looks_like_tasks не видел переименованный индекс; урожай спринта терял автотег после sprint close; ответ на вопрос по инструкции оставлял задачу незабираемой; adopt требовал недостижимого зелёного; путь отчёта триажа не переживал archive; review-specs не имел режима для стыка после слияния; три остатка «шаг 9а» несли предкоммитную позицию закрытия; sprint.md отрицал сам себя в пункте «Сделана». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -142,14 +142,17 @@ python3 $tk sprint close --dir D # конец спринта; --d
|
||||
python3 $tk reopen <слаг> --dir D --reason … # приёмка не сошлась после закрытия
|
||||
```
|
||||
|
||||
`D` — каталог задач проекта; цепочка его разрешения и вызов из чужого контекста
|
||||
описаны в скилле `tasks` («Переносимость»). **Коды выхода** — там же: 1 это
|
||||
дрейф в беклоге, 3 это «каталога нет», и ветвиться на них надо по-разному.
|
||||
`D` — каталог задач проекта, по канону всегда `docs/tasks`; `--dir` передаётся
|
||||
явно каждой командой. Вызов из чужого контекста описан в скилле `tasks`
|
||||
(«Переносимость»). **Коды выхода** — там же: 1 это дрейф в беклоге, 3 это
|
||||
«каталога нет», и ветвиться на них надо по-разному.
|
||||
|
||||
**Слаг спринта заводит `sprint start`** (по умолчанию — дата) и пишет его в
|
||||
`SPRINT.md`; всё заведённое при открытом спринте помечается `sprint:<слаг>`
|
||||
`SPRINT.md`; всё заведённое **при открытом спринте** помечается `sprint:<слаг>`
|
||||
автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без
|
||||
чьей-либо памяти.
|
||||
чьей-либо памяти — но ровно до команды `sprint close`, которая `SPRINT.md`
|
||||
очищает. Отсюда порядок: **урожай заводится до закрытия, слаг для сессии берётся
|
||||
из отчёта `sprint close`** ([references/sprint.md](references/sprint.md)).
|
||||
|
||||
Правки задач делаются мутациями (`edit`, `move`, `close`), а не редактором:
|
||||
руками правится только тело файла. Это правило скилла `tasks`, здесь оно не
|
||||
@@ -165,7 +168,8 @@ python3 $tk reopen <слаг> --dir D --reason … # приёмка не со
|
||||
пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже —
|
||||
**только текстовая**. Опоры, которые остались настоящими:
|
||||
|
||||
- **отчёт триажа** в `openspec/changes/<id>/review/` — независимый артефакт,
|
||||
- **отчёт триажа** в `openspec/changes/archive/<id>/review/` (до архивации —
|
||||
`changes/<id>/review/`) — независимый артефакт,
|
||||
написанный ревью, а не исполнителем; по нему сверяют состав прогона и урожай;
|
||||
- **`SPRINT.md` под git** — `git log -p` показывает, что и когда было закрыто;
|
||||
- **`reopen <слаг> --reason`** — закрытие не окончательно. Приёмка человеком на
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
2. **Сформулируй развилку** с вариантами и последствием каждого, рекомендация —
|
||||
первым вариантом.
|
||||
3. **Вынеси пачкой** через `AskUserQuestion`, не больше трёх за раз.
|
||||
4. **Ответ записывается в тело задачи**, тег снимается `edit <slug> --rm-tag
|
||||
question`, **хук переписывается**: «Решено: …» на вопрос «почему это лежит в
|
||||
беклоге» уже не отвечает.
|
||||
4. **Ответ записывается в тело задачи, раздел «Вопросы» опустошается**, тег
|
||||
снимается `edit <slug> --rm-tag question`, **хук переписывается**: «Решено:
|
||||
…» на вопрос «почему это лежит в беклоге» уже не отвечает. Опустошение
|
||||
раздела — не уборка, а условие взятия: правило и причина в скилле `tasks`,
|
||||
[references/task-format.md](../../tasks/references/task-format.md).
|
||||
|
||||
**Вопросы на задачах-кандидатах разбираются вне очереди порции** — здесь же, на
|
||||
этой сессии, даже если сама задача в порцию переоценки не попала. Иначе правило
|
||||
@@ -69,9 +71,10 @@
|
||||
задачи, заведённые за спринт; при урожае в 15 это две-три порции.
|
||||
- **Отбор порций по порядку:**
|
||||
1. **урожай спринта** — `list --tag sprint:<слаг>`: свежезаведённое ещё не
|
||||
проходило ни одной проверки на нужность. Слаг спринта берётся из
|
||||
`SPRINT.md` (его завёл `sprint start`), тег на задачах проставлен
|
||||
автоматически при заведении — руками не метят и не вспоминают;
|
||||
проходило ни одной проверки на нужность. Тег на задачах проставлен
|
||||
автоматически при заведении — руками не метят и не вспоминают. **Слаг
|
||||
берётся из отчёта `sprint close`, а не из `SPRINT.md`:** сессия идёт после
|
||||
закрытия, а закрытие этот файл очищает;
|
||||
2. дальше **по залежалости** — `list --stale`;
|
||||
3. по потребности — одна секция целиком, один тег (партия ревью), одна цель
|
||||
(`--goal`), список от пользователя.
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
след.
|
||||
|
||||
- **Сделана** — по определению готовности ниже. `close <slug> --implemented`:
|
||||
файл и строка удаляются, следом остаётся коммит. **Закрывает владелец спринта
|
||||
и только после вердикта приёмки** — см. «Кто и когда закрывает».
|
||||
файл и строка удаляются, следом остаётся коммит. **Закрывает агент-оркестратор
|
||||
последним шагом пайплайна, после коммита; приёмка человеком идёт позже и
|
||||
отменяется `reopen`** — см. «Кто и когда закрывает».
|
||||
- **Вышла из спринта** — `sprint drop <slug> --reason …`: возвращается в беклог
|
||||
с вопросом в файле и **без живого незакоммиченного предложения** — иначе при
|
||||
следующем взятии оно столкнётся с новым. Наработки, которые жалко терять,
|
||||
@@ -35,6 +36,13 @@
|
||||
сессии поднимается одной командой `list --tag sprint:<слаг>`. Спринт, закрытый
|
||||
без этого шага, оставляет находки жить в отчётах — то есть нигде.
|
||||
|
||||
**Порядок здесь обязателен: урожай заводится ДО команды `sprint close`.**
|
||||
Автотег ставится по слагу из `SPRINT.md`, а `sprint close` этот файл очищает;
|
||||
заведённое после команды остаётся без тега и в первую порцию следующей сессии
|
||||
не попадёт — молча, потому что пустой `list --tag` выглядит как «урожая не
|
||||
было». Если так уже вышло, тег ставится руками: `add … --tag sprint:<слаг>`,
|
||||
слаг берётся из отчёта `sprint close`.
|
||||
|
||||
**Провал спринта.** Сработал блокер — спринт распускается (`sprint close
|
||||
--dissolve --reason …`), недоделанное возвращается в беклог, новый набор
|
||||
делается после ответа человека. Спринт не «ждёт»: ждать может человек, а
|
||||
@@ -99,7 +107,8 @@
|
||||
2. **Принимает человек на сессии, а не отдельный агент.** Декорреляция
|
||||
исполнителя и приёмщика в момент закрытия **снята** (решение о снятии и его
|
||||
цена — в `SKILL.md`, «Стимулы»). Опоры остались три: сохранённый отчёт триажа
|
||||
в `openspec/changes/<id>/review/` — независимый артефакт, `SPRINT.md` под git
|
||||
в `openspec/changes/archive/<id>/review/` (до архивации — `changes/<id>/review/`)
|
||||
— независимый артефакт, `SPRINT.md` под git
|
||||
и `reopen`. Переоценка на сессии и есть момент, когда критерии видит не
|
||||
исполнитель.
|
||||
3. **Расхождение — дефект критериев.** Приёмщик правит критерии и возвращает
|
||||
|
||||
Reference in New Issue
Block a user