Имя описывало устройство, а не предмет: «пайплайн» говорит, что внутри конвейер, — а плагин занят кодом по задачам, и с появлением чекпоинтов он уже не конвейер в чистом виде. Набор имён стал параллельным: docs / tasks / code / git, каждое называет материал. Заодно review-pipeline стал review — слово ушло из плагина целиком, а не наполовину; скиллы выровнялись: resolve / review / openspec. Журнал версий канона переписан вместе со всеми, DECISIONS.md — нет. Разрез по типу высказывания, а не файла: наблюдение и причина неприкосновенны, предписание и адрес обязаны оставаться исполнимыми. Запись версии 10 велит «проверить, что плагин av-dev-pipeline установлен» — проект, дошедший до неё, выполнил бы невыполнимое.
630 lines
52 KiB
Markdown
630 lines
52 KiB
Markdown
---
|
||
name: resolve
|
||
description: "Решить одну задачу от постановки до закрытия. На входе путь к файлу задачи, её слаг или просто текст. Обычная задача идёт циклом Spec Driven Development: opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие. Исследовательская (тип research, сырая идея, мутная постановка) начинается раньше: opsx explore и чекпоинт вариантов — два-четыре способа решить, с ценой каждого и рекомендацией; выбор оседает по адресу, который назвала сама задача. Между чекпоинтами работа идёт без согласований. Использовать, когда просят взять, сделать или решить задачу, довести идею до реализации, разобраться с записью из беклога."
|
||
---
|
||
|
||
# Решение одной задачи
|
||
|
||
Проводит **одну** задачу от постановки до закрытия. Между плановыми
|
||
остановками — без согласований: механику не обсуждаем, делаем.
|
||
|
||
Тонкая обёртка над каноническими скиллами `opsx:explore` / `opsx:propose` /
|
||
`opsx:apply` / `opsx:archive` — зови их через Skill, не переизобретай их шаги.
|
||
Ревью — скилл `av-dev-code:review`; он же держит правило выбора
|
||
метки, а называет её агент `review-scope` — один раз на задачу, для обеих стадий
|
||
ревью.
|
||
|
||
## Предпосылки
|
||
|
||
- **OpenSpec и скиллы `opsx:*` — жёсткая предпосылка, а не опция.** На них стоят
|
||
шаги 2, 6 и 8, проход `review-specs` и ревью дизайна (они завязаны на
|
||
`openspec/changes/<id>/specs/*/spec.md` и на `openspec validate --strict`).
|
||
**Проект без OpenSpec этим скиллом не ведётся** — подключай OpenSpec, а не
|
||
вырождай цикл: ветка деградации здесь не пишется, потому что непроверенная
|
||
ветка деградации хуже честного отказа.
|
||
- **Проектные копии этих скиллов и агентов удаляются при установке плагина**
|
||
(`.claude/skills/` — и голые имена `resolve`, `task-pipeline`,
|
||
`review-pipeline`, и с префиксом проекта: `<проект>-task-pipeline`,
|
||
`<проект>-review-pipeline`; `.claude/agents/<проект>-review-*.md`). Две копии
|
||
одного скилла расходятся, и побеждает та, что короче названа.
|
||
|
||
### Обращение к соседним плагинам
|
||
|
||
**Копия.** Дом — `shared/plugin-boundary.md` в репозитории плагинов: правило
|
||
общее для всех, кто зовёт чужое, и ни один плагин им не владеет. Правится дом, а
|
||
не этот файл.
|
||
|
||
<!-- копия: граница-плагинов из shared/plugin-boundary.md -->
|
||
|
||
Плагины `av-dev` ставятся порознь, и ни один не вправе считать, что сосед на
|
||
месте.
|
||
|
||
**Чужой скилл зовётся полным именем** — `av-dev-docs:canon`, `av-dev-tasks:tasks`,
|
||
`av-dev-code:review`. Короткое имя может разрешиться в устаревшую проектную копию
|
||
из `.claude/skills/`, и подмены не будет видно ни в докладе, ни в поведении.
|
||
|
||
**Путь в дерево чужого плагина не пишется никогда.** `$CLAUDE_PLUGIN_ROOT` ведёт
|
||
только в свой плагин; вычисленный от него путь к соседу либо не откроется, либо
|
||
откроет чужую установку. Нужен чужой справочник — зови владеющий им скилл, он
|
||
прочитает его сам.
|
||
|
||
**Вызов не разрешился — плагина в проекте нет.** Это исход, а не поломка: назови
|
||
строкой доклада, чего теперь не делает никто, и продолжай работу. Молчать нельзя,
|
||
пропуск неотличим от сделанного; выдумывать обходной путь нельзя тоже.
|
||
|
||
**Присутствие узнаётся вызовом или следом в проекте, но не объявлением.** Перечня
|
||
установленных плагинов проект не ведёт — он разошёлся бы с действительностью
|
||
молча. Что сосед здесь работал, видно по заведённому им файлу: `docs/.pm.json` —
|
||
канон, `<каталог задач>/.tasks.json` — задачи, `openspec/config.yaml` — конвейер.
|
||
|
||
<!-- /копия: граница-плагинов -->
|
||
|
||
Скилл зовёт `av-dev-code:review`, `av-dev-docs:docs` и
|
||
`av-dev-tasks:tasks`. Чем оборачивается отсутствие каждого — на самих шагах и в
|
||
разделе «Границы».
|
||
|
||
Перед стартом прочитай `CLAUDE.md` проекта и то, на что он ссылается, если ещё
|
||
не в контексте. Проектные факты, нужные ревью — инварианты, семантика гейта,
|
||
объёмы, модель угроз, прецеденты, — живут в **документах канона** `av-dev-docs`;
|
||
карта «что где» — `references/project-facts.md` конвейера ревью.
|
||
|
||
**Документов канона нет — проект к нему не приведён.** Скажи это строкой и
|
||
предложи скилл `av-dev-docs:canon`: одна операция на проект против поразрядной
|
||
деградации на каждой задаче. Работу при этом не останавливай.
|
||
|
||
## Вход
|
||
|
||
Задача задаётся **путём к файлу, именем файла, слагом или просто текстом**.
|
||
Ничего из этого не задано — попроси у вызывающего и остановись; сам в беклог не
|
||
лезь и приоритеты не интерпретируй: что делать дальше, решает не этот скилл.
|
||
|
||
**Запись, не готовая к работе, в работу не берётся.** У типа `research` это
|
||
проверяемо и потому обязательно: нет непустого раздела **«Вопрос»** — это не
|
||
разведка, а сырьё, и его сперва доводят до вопроса. Скажи это исходом и назови,
|
||
чего не хватает; штурмовать сырьё за автора — не работа этого скилла.
|
||
|
||
У остальных типов схему держит `av-dev-tasks` (обязательные разделы, не меньше
|
||
двух критериев приёмки). Прочитай запись и, если видно, что схема не выполнена,
|
||
скажи это строкой — но работу не останавливай: у типов действия пробел лечится
|
||
по ходу, а у разведки без вопроса лечить нечего.
|
||
|
||
## Две ветки
|
||
|
||
Развилка одна и стоит на входе:
|
||
|
||
- **обычная задача** — что делать, понятно; спорно только как. Идёт с шага 1;
|
||
- **исследовательская** — тип `research`, сырая идея, новое и незнакомое, мутная
|
||
постановка. Идёт с шага Р1, и там её ждёт **свой** чекпоинт: варианты решения
|
||
обсуждаются **до** того, как написано первое требование.
|
||
|
||
Признак не в объёме работы, а в том, **есть ли у задачи один очевидный способ
|
||
решения**. Его нет — обсуждать варианты после `propose` поздно: предложение уже
|
||
воплотило один из них, и разговор пойдёт не о выборе, а о переделке.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
in["вход: файл, слаг или текст"]
|
||
fork{"есть очевидный<br/>способ решения?"}
|
||
r1["Р1. понять вопрос<br/>сырьё без «Вопроса» — отказ"]
|
||
r2["Р2. opsx:explore — груминг"]
|
||
r3(["Р3. ЧЕКПОИНТ: варианты<br/>2–4 способа, цена каждого,<br/>рекомендация"])
|
||
rout["исход без кода:<br/>ответ записан / отказ / родились задачи"]
|
||
s1["1. прочитать задачу<br/>критерии приёмки выписать сразу"]
|
||
s2["2. opsx:propose — change, дельта-спеки, tasks.md"]
|
||
s3["3. разметка — review-scope:<br/>размер, сложность, метка, план тем"]
|
||
s4["4. ревью дизайна, состав по метке<br/>+ отработка замечаний"]
|
||
s5(["5. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
|
||
s6["6. opsx:apply — код, гейт,<br/>поведенческая верификация"]
|
||
s7["7. ревью кода, та же метка<br/>+ отработка замечаний"]
|
||
s8["8. opsx:archive"]
|
||
s9["9. синк документации — av-dev-docs:docs"]
|
||
s10["10. коммит работы — av-dev-git:commit"]
|
||
s11["11. закрыть задачу — av-dev-tasks:tasks,<br/>вторым коммитом учёта"]
|
||
|
||
in --> fork
|
||
fork -->|"да"| s1
|
||
fork -->|"нет"| r1
|
||
r1 --> r2 --> r3
|
||
r3 -->|"выбран способ"| s1
|
||
r3 -.->|"кода не будет"| rout
|
||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10 --> s11
|
||
s3 -.->|"план задачи: та же метка"| s7
|
||
s7 -.->|"находка отменяет дизайн"| s5
|
||
```
|
||
|
||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||
расхождении прав текст.
|
||
|
||
## Автономность и два плановых стопа
|
||
|
||
**Между чекпоинтами умолчание прежнее — делать, а не спрашивать.** Чекпоинты не
|
||
отменяют автономность, они дают развилкам плановое место, куда копиться.
|
||
|
||
Разрез простой:
|
||
|
||
- развилка найдена **до** ближайшего чекпоинта — она его и ждёт. Не спрашивай
|
||
отдельно: чекпоинт рядом и стоит дёшево, а три вопроса подряд стоят дороже
|
||
одного разговора;
|
||
- развилка найдена **после** последнего чекпоинта — старое правило: **запиши
|
||
вопрос и доведи остаток**, не останавливаясь.
|
||
|
||
Запись вопроса устроена так:
|
||
|
||
1. **Запиши там, где проект держит вопросы** (секция беклога, файл задачи,
|
||
трекер — это знает проект). Проект не сказал, куда, — отдельной секцией
|
||
`Вопросы` в своём докладе, и это тоже исход. Тело отвечает на три вещи: **что
|
||
именно решить**, **какие есть варианты и цена каждого**, **что стоит, пока
|
||
решения нет**. Плюс твоя рекомендация — человек чаще соглашается, чем выбирает
|
||
заново, и готовое суждение экономит ему весь контекст.
|
||
2. **Переформулируй задачу на остаток** — то, что делается без этого решения.
|
||
Назови границу: докуда доводим сейчас.
|
||
3. Доведи остаток до конца и закоммить. Задача не «висит на вопросе», она сделана
|
||
в объявленных границах.
|
||
|
||
**Что остатком не является — правило живёт не здесь.** Канонический текст с обеими
|
||
оговорками — в плагине `av-dev-tasks`, скилл `av-dev-tasks:session`, раздел
|
||
`## Вопрос, блокер, необратимое`, подраздел «Отличать вопрос от застревания».
|
||
Правило принадлежит управлению задачами, потому что решает **сделана задача или
|
||
вышла**, — это исход планирования, а не исполнения. **Ссылайся, не
|
||
пересказывай:** копия, заведённая здесь, уже однажды разошлась с оригиналом и
|
||
потеряла из перечня самое необратимое — запись **наружу**.
|
||
|
||
Коротко, чтобы знать, когда идти читать: остаток проверяется двумя порогами —
|
||
**материализация нерешённого** (запись состояния, зависящего от неотвеченного
|
||
вопроса) и **пол по пользе** (из остатка пропала польза, названная в постановке).
|
||
Оба порога — стоп: первый поднимает решение до начала записи, второй даёт исход
|
||
«не доведена».
|
||
|
||
Плагин `av-dev-tasks` не подключён — правило не отменяется, а становится
|
||
осторожнее: прежде чем записать зависящее от нерешённого куда бы то ни было —
|
||
в хранилище, в журнал, в витрину или наружу, — спрашивай человека.
|
||
|
||
Нет полезного остатка — задача заканчивается исходом «не доведена», вопрос
|
||
записан, ничего не коммитится наполовину.
|
||
|
||
### Когда спрашивать вне чекпоинтов
|
||
|
||
По другому основанию — не «сложное решение», а **необратимое действие**:
|
||
|
||
- деплой, выкладка наружу, смена публичного адреса или токенов;
|
||
- удаление или перезапись рабочих данных, включая подрезку архивов;
|
||
- всё, что уходит за пределы машины.
|
||
|
||
Здесь ошибка не откатывается коммитом, поэтому спрашиваем даже когда решение
|
||
кажется очевидным.
|
||
|
||
Стиль правок — заточка под проект и конвенции, right-size, без золочения.
|
||
|
||
## Границы: чем этот скилл не владеет
|
||
|
||
- **Беклогом, целями и приоритетами.** Задача приходит извне. Скилл её не
|
||
выбирает, не приоритизирует, не заводит и не переоценивает.
|
||
- **Форматом задач.** Индексы руками не правятся, путь к скрипту учёта не
|
||
выдумывается: этим владеет `av-dev-tasks:tasks` (шаг 11). Закрытие — работа
|
||
этого скилла, и это осознанное решение с названной ценой: **приёмщик и
|
||
исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на сессии
|
||
возвращает задачу `reopen` с причиной, а доклад по критериям приёмки становится
|
||
единственным, по чему приёмка вообще возможна.
|
||
- **Заведением задач из урожая ревью.** Отложенные находки отдаются **списком**;
|
||
превращать их в задачи — работа того, кто ведёт задачи проекта.
|
||
- **Определением ценности.** «Нужна ли эта функциональность» — не вопрос этого
|
||
скилла ни на одном шаге. Чекпоинт спрашивает «так ли решаем», а не «надо ли».
|
||
|
||
## Наблюдаемые исходы
|
||
|
||
Ровно четыре, и каждый обязан быть назван в докладе прямо:
|
||
|
||
- **сделана** — определение готовности выполнено целиком;
|
||
- **не доведена** — с причиной и с записанным вопросом; что именно сделано и до
|
||
какой границы, названо явно. Сюда же попадает чекпоинт, на котором человек
|
||
решение не одобрил;
|
||
- **оказалась крупнее задачи** — распознаётся **до заведения change**, иначе его
|
||
придётся выбрасывать. Дальше — декомпозиция, и это не работа этого скилла;
|
||
- **знание вместо изменения** — только у исследовательской ветки: ответ записан
|
||
по названному адресу, кода задача не потребовала. Это полноправный исход, а не
|
||
недоведённая работа.
|
||
|
||
## Определение готовности
|
||
|
||
Задача сделана, когда верно всё:
|
||
|
||
1. гейт проекта зелёный;
|
||
2. ревью проведено, **план прогона сверен с исходом по каждой теме**, темы без
|
||
отчёта и без дома названы в границах покрытия;
|
||
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
|
||
чекпоинт был пройден заново;
|
||
4. change заархивирован, дельты влиты в актуальные спеки;
|
||
5. коммит сделан в текущую ветку;
|
||
6. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
|
||
оракул и наблюдаемый исход** — «прогнал вот это, увидел вот то». Это **доклад,
|
||
а не сертификация: приёмка — не работа этого скилла.** Исполнитель, ставящий
|
||
себе галочку «принято», проверяет свою работу своим же взглядом — по границе
|
||
это может делать только приёмщик, разведённый с исполнителем. Критерии приходят
|
||
снаружи; скилл их не сочиняет и не занижает. Расхождение «по каждому критерию
|
||
исход есть, а суть задачи не достигнута» — дефект критериев, и о нём
|
||
сообщается, а не молча дорабатывается.
|
||
|
||
У разведки, кончившейся знанием, определение своё и короткое: **ответ записан по
|
||
адресу, который назвала задача**, и в нём есть провенанс у каждого числа.
|
||
|
||
## Исследовательская ветка
|
||
|
||
### Р1. Понять вопрос
|
||
|
||
Прочитай запись. У типа `research` в ней два обязательных раздела, и оба нужны
|
||
тебе прямо сейчас: **«Вопрос»** — на что отвечаем, **«Куда ляжет ответ»** — по
|
||
какому адресу он ляжет. Адрес назван заранее не из аккуратности: ответ, не
|
||
имеющий дома, остаётся в переписке, и через квартал разведку заказывают заново.
|
||
|
||
Вопроса нет — исход «не доведена» с причиной «запись это сырьё»: назови, что
|
||
нужно дописать, и остановись. Адреса нет, а вопрос есть — назначь адрес сам и
|
||
скажи об этом строкой: разведка без дома для ответа хуже несделанной.
|
||
|
||
Задача не из каталога (пришла текстом) — адреса у неё нет по построению. Тогда
|
||
дом ответа — `design.md` того change, который родится дальше; кода не будет —
|
||
`docs/research/`, и это тоже говорится строкой.
|
||
|
||
### Р2. Груминг — `opsx:explore`
|
||
|
||
Вызови Skill `opsx:explore`. Читай документы проекта, а не только запись:
|
||
граница домена и «чем проект **не** является» из паспорта отсекают половину
|
||
вариантов до того, как их начнут сравнивать. **В explore не пишем код.**
|
||
|
||
Развилку грумминга **не записывай вопросом** — она и есть предмет следующего
|
||
шага. Это отличие от обычной ветки: там развилка уходит в запись, здесь она
|
||
копится в чекпоинт.
|
||
|
||
### Р3. Чекпоинт: варианты
|
||
|
||
**Остановись и покажи человеку способы решить.** Это первый из двух плановых
|
||
стопов, и он существует потому, что после `propose` выбор уже сделан
|
||
предложением.
|
||
|
||
Форма — короткая, экран текста:
|
||
|
||
- **вопрос**, на который отвечаем, одной фразой (он уже есть в записи);
|
||
- **2–4 варианта**, не больше. Больше четырёх — это не выбор, а список: человек
|
||
не сравнит, а признает свою неспособность сравнить и попросит рекомендацию.
|
||
У каждого варианта: в чём суть простыми словами, **что даёт**, **чего стоит**,
|
||
**что становится невозможным** (это ловится хуже всего и стоит дороже всего);
|
||
- **рекомендация с причиной**. Человек чаще соглашается, чем выбирает заново;
|
||
- что известно **недостоверно** и как это проверить, если проверять дёшево.
|
||
|
||
Что нельзя: приносить варианты, различающиеся только реализацией; прятать
|
||
отвергнутое (отвергнутый вариант с названной причиной — половина будущего ADR);
|
||
приносить один вариант и называть это выбором.
|
||
|
||
**Выбор оседает по адресу.** У `research` это раздел «Куда ляжет ответ». У
|
||
остальных — `design.md` change, который родится на шаге 2, разделом
|
||
«рассмотренные варианты». Не в переписку: разговор, из которого ничего не
|
||
записано, повторяется через месяц целиком.
|
||
|
||
Три исхода чекпоинта:
|
||
|
||
- **выбран способ** — идёшь на шаг 1 общей ветки;
|
||
- **ответ и есть исход** — работа кончается знанием: запиши ответ по адресу,
|
||
доложи исход «знание вместо изменения» и закрой задачу (шаг 11). Провенанс у
|
||
каждого числа обязателен: число без источника проход ревью обязан читать как
|
||
условие, а не как замер;
|
||
- **разведка родила задачи** — исход «оказалась крупнее задачи». Нарезка не твоя
|
||
работа: отдай список формулировками и остановись.
|
||
|
||
## Шаги
|
||
|
||
### 1. Прочитать задачу
|
||
|
||
Прочитай запись и связанные спеки и черновики.
|
||
|
||
Проект даёт задаче **критерии приёмки** — выпиши их сразу: на шаге 2 они уезжают
|
||
в `tasks.md` change. Файл задачи может быть удалён до коммита, а критерии обязаны
|
||
его пережить.
|
||
|
||
Здесь же проверка на «крупнее задачи»: видно, что одним заходом это не
|
||
мерджится, — объявляй исход **до** заведения change.
|
||
|
||
### 2. Завести change — `opsx:propose`
|
||
|
||
Вызови Skill `opsx:propose`. Получаем `proposal.md`, дизайн, дельта-спеки
|
||
(`ADDED`/`MODIFIED`/`REMOVED Requirements`), `tasks.md`. Каждое `### Requirement`
|
||
содержит `SHALL`/`MUST`; структурные заголовки английские, сценарии
|
||
`GIVEN/WHEN/THEN`. Прогони `openspec validate --strict <id>`.
|
||
|
||
Критерии приёмки задачи, если они были, копируются в `tasks.md` отдельным блоком.
|
||
Варианты, разобранные на чекпоинте Р3, — в `design.md`, с причиной отказа по
|
||
каждому отвергнутому.
|
||
|
||
**`proposal.md` пишется так, чтобы его понял человек, не читавший спек.** Это не
|
||
стилистическое пожелание: из него собирается чекпоинт шага 5, и переписывать его
|
||
там заново значит завести второй дом для одного объяснения. Требование стоит в
|
||
`openspec/config.yaml`, `rules.proposal` — то есть применяется в момент
|
||
порождения артефакта, а не вспоминается после.
|
||
|
||
### 3. Разметка задачи — агент `review-scope`
|
||
|
||
**Один запуск на всю задачу, и он обслуживает оба чекпоинта ревью.** Запусти
|
||
агента `review-scope`, дав ему корень проекта, идентификатор change, базу диффа и
|
||
запись задачи. Кода на этот момент нет, и это условие его работы, а не помеха.
|
||
|
||
Он возвращает **план задачи**:
|
||
|
||
- **размер** (малое / среднее / крупное) и **сложность** (знакомое /
|
||
незнакомое), каждое с обоснованием по факту;
|
||
- **метку** как максимум по двум осям: `small`, `medium` или `large`;
|
||
- **состав ревью дизайна** — что звать на шаге 4;
|
||
- **таблицу тем** «тема → дом → глубина → кто закрывает» — для шага 7;
|
||
- разнесение документов проекта по трём категориям и строку про директивы.
|
||
|
||
**Метку выбираешь не ты.** Раньше состав ревью дизайна называл сам оркестратор —
|
||
то есть тот, кто только что довёл предложение до `propose`. Разведённости с
|
||
автором в этой точке не было вовсе; теперь есть.
|
||
|
||
**План держи в контексте до конца задачи.** На диск он не пишется: файл-план стал
|
||
бы четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, пережил
|
||
бы задачу и разошёлся бы с ней молча. Прервался прогон — повтори шаг 3, это самый
|
||
дешёвый его проход.
|
||
|
||
**Разметка повторяется ровно в одном случае** — если правки изменили сами
|
||
**дельта-спеки**: план выведен из них, и план по отменённым требованиям назовёт
|
||
не те темы. Во всех прочих случаях, включая переделку формы кода на шаге 7,
|
||
метка остаётся прежней.
|
||
|
||
### 4. Ревью дизайна — ДО кода, состав по метке
|
||
|
||
Вызови Skill **`av-dev-code:review`**, дав ссылку на change `<id>`,
|
||
**план разметки с шага 3** и указание, что это ревью дизайна.
|
||
|
||
Состав приходит планом, а не решается здесь:
|
||
|
||
| Метка | Проходы на предложении |
|
||
|---|---|
|
||
| `small` | `specs` |
|
||
| `medium` | `specs`, `rubric` |
|
||
| `large` | `specs`, `rubric`, `architecture` + вопрос автору о трёх формах решения |
|
||
|
||
`review-specs` в режиме «дизайн ДО кода» идёт **на каждой задаче**: это самый
|
||
дешёвый чекпоинт конвейера, и он ловит то, что на готовом коде уже не чинят.
|
||
Остальные включаются меткой, потому что стадия стоит на каждой задаче и каждый
|
||
лишний проход здесь умножается на число задач.
|
||
|
||
Смысл стадии: архитектурная находка на готовом коде стоит переписывания и потому
|
||
игнорируется — та же находка здесь стоит абзаца обсуждения. Если `review-rubric`
|
||
запускался, перенеси его рубрику в `tasks.md` как приёмочные критерии; там же уже
|
||
лежат критерии от постановки, если они были.
|
||
|
||
**Отработка замечаний, и она идёт до чекпоинта, а не после:**
|
||
|
||
- мелочь и явные улучшения — правь сам в спеках и дизайне;
|
||
- развилки (компромисс, scope, инвариант) — **не в запись, а в чекпоинт**: он
|
||
следующим шагом, и это ровно то, ради чего он поставлен здесь;
|
||
- после правок перепрогони `openspec validate --strict <id>`.
|
||
|
||
### 5. Чекпоинт: объяснение
|
||
|
||
**Остановись и объясни человеку, что происходит.** Второй плановый стоп и
|
||
единственный обязательный для всех задач.
|
||
|
||
Он стоит **после** ревью дизайна намеренно. Человек читает объяснение, уже
|
||
просеянное машиной: то, что поймал бы `review-specs`, до него не доходит, а
|
||
внимание — самый дорогой ресурс процесса, и тратить его на выловимое машиной
|
||
нельзя.
|
||
|
||
**Объяснение не сочиняется заново — оно собирается из артефактов**, `proposal.md`
|
||
и `design.md`. Третий пересказ был бы третьим домом одного и того же и разошёлся
|
||
бы с обоими. Что показываешь:
|
||
|
||
- **в чём проблема** — словами домена из паспорта, без имён модулей и функций;
|
||
- **как решаем** — суть одним абзацем. Не пересказ дельта-спек: спека нормирует,
|
||
а здесь объясняют;
|
||
- **что человек увидит иначе**, когда это будет сделано;
|
||
- **чего мы намеренно не делаем** и почему — граница scope ловится хуже всего;
|
||
- **чем рискуем и что осталось нерешённым** — сюда съезжаются развилки,
|
||
накопленные до этого места, и находки ревью с пометкой `развилка`;
|
||
- **что дальше**, если возражений нет.
|
||
|
||
Проверка на «простой язык» одна и механическая: **в тексте нет `SHALL`, нет имён
|
||
файлов и функций там, где вещь называется по-русски, и нет слов, которых нет в
|
||
паспорте проекта.** Не проходит — переписывай, а не объясняй, почему иначе
|
||
нельзя.
|
||
|
||
Длина — экран. Длинное объяснение не читают, а пролистывают, и чекпоинт
|
||
превращается в ритуал одобрения.
|
||
|
||
Три исхода:
|
||
|
||
- **согласен** — идёшь на шаг 6;
|
||
- **скорректировать** — правишь спеки и дизайн по сказанному. Изменились
|
||
**дельта-спеки** — повтори шаг 3 (разметка выведена из них) и ту часть ревью
|
||
дизайна, которой касается правка; затем чекпоинт **заново**. Правка внутри
|
||
дизайна без спек — повтори только чекпоинт;
|
||
- **не одобрено** — исход «не доведена» с причиной. Change остаётся
|
||
незаархивированным, задача не закрывается, ничего не коммитится наполовину.
|
||
|
||
### 6. Написать код — `opsx:apply`
|
||
|
||
Вызови Skill `opsx:apply` для реализации `tasks.md`. Код — по конвенциям проекта
|
||
(каталог `docs/conventions/`). Меняешь схему — обнови её описание в документации
|
||
тем же change, если проект этого требует: гейт обычно это проверяет.
|
||
|
||
Прогони гейт и добейся зелёного — он же гейт следующего шага.
|
||
|
||
**Поведенческая верификация.** Если задача меняет реальное поведение (новый
|
||
эндпоинт, разбор входа, схема, форма ответа) — зелёных юнит-тестов мало. Подними
|
||
изменение вживую командой из раздела команд `CLAUDE.md` и прогони сценарий.
|
||
Пропусти только для чисто внутренних правок без наблюдаемого рантайма.
|
||
|
||
**Сервис не оставляем лежать.** Если запуск упал — почини или откати до конца
|
||
шага.
|
||
|
||
### 7. Ревью кода — та же метка
|
||
|
||
Вызови Skill **`av-dev-code:review`**, дав ссылку на change `<id>`,
|
||
базу диффа, **план разметки с шага 3** и режим запуска.
|
||
|
||
**Метку ты не выбираешь, и это правило, а не упрощение.** Её назвал
|
||
`review-scope` ещё на шаге 3 — по размеру и сложности, с обоснованием по каждой
|
||
оси. Причина в разведённости: ты только что написал этот код, и решать, насколько
|
||
глубоко его проверять, тебе нельзя — под давлением «я почти закончил» решение
|
||
известно заранее. Правило выбора живёт в скилле конвейера —
|
||
`av-dev-code:review`, `references/review-levels.md`; проектные
|
||
триггеры — в `docs/review.*`, подраздел «Триггеры метки».
|
||
|
||
**Метка не пересматривается по факту диффа.** Дифф может выйти крупнее, чем
|
||
ожидалось при разметке, — это не повод её поднимать: пересмотр означал бы второй
|
||
запуск разметчика, ровно то, ради устранения чего он и переехал на шаг 3.
|
||
|
||
**Считаешь метку заниженной — скажи это в докладе строкой, а не переспорь.**
|
||
Разметчик вправе и поднять, и понизить; твоё несогласие это факт для человека, а
|
||
не команда конвейеру. Место, где такое несогласие превращается в изменение
|
||
правил, — журнал дефектов `docs/review.md`, и только постфактум.
|
||
|
||
**Плана нет — ревью кода не запускается.** Триаж требует план обязательным
|
||
входом: без него он не может сверить, все ли размеченные темы вернули отчёт, а
|
||
эта сверка — единственная защита от молчащего пропуска. Потерял план (прервалась
|
||
сессия, ушёл контекст) — повтори шаг 3, а не гони прогон без него.
|
||
|
||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||
знает свои рёбра: гейт открывает опиниативные проходы, проходы с пометкой «держит
|
||
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
||
доказанной), триаж — сток. Просить **`линейно`** нужно только по причине, и она
|
||
называется строкой: так сказал оператор; машина занята чем-то ещё; идёт разбор
|
||
самого конвейера.
|
||
|
||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||
покрытия.
|
||
|
||
**Сверь план прогона с исходом, прежде чем коммитить.** Отчёт начинается планом
|
||
разметчика — таблицей «тема → дом → глубина → кто закрывает», — и против каждой
|
||
темы обязан стоять исход. Тема без отчёта и тема без дома — разные вещи, и обе
|
||
должны быть названы. Реестр короткий (шесть тем ядра плюс свои) — сверка стоит
|
||
одного взгляда.
|
||
|
||
#### Отработка, и здесь появляется одно новое правило
|
||
|
||
Помеченное `инлайн` чини сам и не логируй. `развилка` — вопросом в запись (он уже
|
||
сформулирован триажем, его остаётся перенести). После правок — снова гейт.
|
||
|
||
**Находка, отменяющая одобренный дизайн, отменяет и одобрение.** Признак
|
||
проверяемый: **меняются ли дельта-спеки**.
|
||
|
||
- не меняются — находка внутри дизайна, дожимай сам, это обычная отработка;
|
||
- меняются — решение стало другим, а одобрено было прежнее. Повтори шаг 3
|
||
(разметка выведена из дельта-спек) и **вернись на чекпоинт шага 5** с тем, что
|
||
изменилось и почему.
|
||
|
||
Тихо переделать утверждённое нельзя. Чекпоинт, который можно обойти находкой
|
||
ревью, не значит ничего, а человек при этом уверен, что одобрил именно то, что
|
||
уехало в коммит.
|
||
|
||
**Урожай — списком, не задачами.** Отложенные находки (реальный `major` не для
|
||
этого мерджа, развилка, решённая «потом», пачка `nit`) собери в секцию доклада
|
||
`Урожай`: формулировка, оракул, провенанс. Задачи из него **заводит не этот
|
||
скилл** — у того, кто ведёт задачи проекта, своя нарезка, свой формат и свои
|
||
правила дублей. Твоя обязанность — не потерять и передать.
|
||
|
||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||
превращается в ложное ощущение проверенности.
|
||
|
||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||
|
||
### 8. Архивировать — `opsx:archive`
|
||
|
||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||
|
||
### 9. Синк документации
|
||
|
||
**Вызови Skill `av-dev-docs:docs`**: он владеет содержимым документов канона и
|
||
ведёт чек-лист синка.
|
||
|
||
**Правило одно и оно жёсткое: принуждённое отрицание.** Доклад обязан назвать
|
||
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
|
||
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
|
||
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
|
||
работает только обязательное отрицание.
|
||
|
||
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
|
||
`av-dev-docs:docs`, и копия уже однажды разошлась с оригиналом, потеряв два
|
||
триггера.
|
||
|
||
**Плагина `av-dev-docs` в проекте нет** — путь в его дерево не разрешится ниоткуда,
|
||
поэтому за списком иди в **свой** reference:
|
||
[references/project-facts.md](../review/references/project-facts.md)
|
||
конвейера ревью перечисляет все документы канона с их предметом. Пройди по этому
|
||
перечню — каждый документ получает строку, отрицание остаётся обязательным.
|
||
Триггеры при этом ты знаешь хуже, и это называется в докладе строкой: «синк
|
||
сделан по перечню документов, без списка триггеров — плагина `av-dev-docs` нет».
|
||
Канона в проекте тоже нет — назови это исходом и предложи `av-dev-docs:canon`.
|
||
|
||
### 10. Коммит
|
||
|
||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||
создавай и не переключай, ничего не пушь.
|
||
|
||
Сообщение — по-русски, скиллом `av-dev-git:commit`, если он подключён (первая
|
||
строка «что сделано», тело списком 1–3 пункта, без трейлеров). Одна задача — один
|
||
осмысленный коммит.
|
||
|
||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||
|
||
**Вызови Skill `av-dev-tasks:tasks`** и попроси закрыть задачу как реализованную —
|
||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||
|
||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||
|
||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||
правка индексов (их имена знает `av-dev-tasks`, не ты) — это правки в рабочем
|
||
дереве, и оставить их незакоммиченными нельзя: закрытие, не доехавшее до основной
|
||
ветки, оставит задачу открытой молча, а опора «индексы под git показывают, что и
|
||
когда закрыто» без коммита — пустые слова. Сообщение короткое, про учёт, а не про
|
||
работу: `закрыта задача <slug>`. Это второй коммит осознанно: правило «одна задача
|
||
— один осмысленный коммит» про работу, а учёт — не работа.
|
||
|
||
Разведка, кончившаяся знанием, закрывается так же — но перед этим убедись, что
|
||
ответ **записан по названному адресу и закоммичен**. Закрытая разведка без
|
||
записанного ответа не оставляет следа вообще: файл задачи удалён, ответ был в
|
||
переписке.
|
||
|
||
Плагина в проекте нет — вызов не разрешится. Тогда **ничего не выдумывай**: скажи
|
||
в докладе, что учёт задач остаётся за владельцем, и назови исход.
|
||
|
||
## Доклад
|
||
|
||
Коротко, и в нём обязательно:
|
||
|
||
- **исход** одним из четырёх слов и, если не «сделана», чем ограничен результат;
|
||
- что сделано, какие вопросы записаны и куда;
|
||
- **что было одобрено на чекпоинте и совпало ли с тем, что уехало в коммит** —
|
||
расхождение здесь называется прямо, даже если оно мелкое;
|
||
- ссылка на архивный change и хеш коммита;
|
||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||
это доклад приёмщику, а не отметка «принято»;
|
||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, провенанс);
|
||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||
запускались и что проверить было невозможно. Доклад без неё сообщает
|
||
«проверено», не сообщая, что именно.
|
||
|
||
## Тонкости
|
||
|
||
- **Не завязывайся на основную ветку и корень репозитория.** Скилл работает в
|
||
текущем worktree и на текущей ветке: не делай `git checkout`/`switch`, не
|
||
создавай веток, не пушь.
|
||
- Обычная задача с очевидным решением проходит **один** чекпоинт, и это норма, а
|
||
не упрощение. Два чекпоинта — цена незнания, а не признак серьёзности задачи.
|
||
- Гейт блокирует: пока он красный, опиниативные проходы не запускаются. Чинить и
|
||
перезапускать, а не «посмотреть заодно».
|
||
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
|
||
подтверждать механику: чекпоинты — единственные места, где ждут ответа.
|
||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||
расхождение с одобренным — отдельным пунктом доклада.
|