слияние: три плагина стали одним av-dev, скиллы получили префиксы
Каталоги, агенты и общие дома переехали в av-dev/; скиллы названы по прежнему плагину — doc-*, task-*, code-*, с двумя смысловыми именами вместо тавтологии: doc-sync вместо docs, task-track вместо tasks. Манифесты сведены к двум плагинам. Пространства имён вызовов и пути внутри дерева переписаны машинно; проза, которая называет прежние плагины отдельными, идёт следующим шагом.
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
---
|
||||
name: code-resolve
|
||||
description: "Взять одну задачу и довести её до закрытия. Одна точка входа, три сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ известен и меняется поведение — сценарий решения: цикл Spec Driven Development (opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие). Способ известен, а спека не меняется (тип chore: тулчейн, зависимости, сборка, гит-хуки, перенос, чистка) — сценарий обслуживания: правка → гейт со сверкой состава проверок → ревью фиксированным планом без change (autotests, operations, плюс conventions, если тронут код) → синк документации → коммит → закрытие; планового стопа нет, change не заводится. Нашлась дельта-спека — задача оказалась шире своего типа: стоп с объяснением простым языком и двумя решениями человека, переформулировать запись в fix или feature и решать её процессом того типа следующим прогоном либо прекратить работу. Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → вычитка написанного → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст. Использовать, когда просят взять, сделать или решить задачу, обновить зависимости или сборку, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога."
|
||||
---
|
||||
|
||||
# Работа над одной задачей
|
||||
|
||||
Проводит **одну** задачу от постановки до закрытия. Вокруг планового стопа — без
|
||||
согласований: механику не обсуждаем, делаем.
|
||||
|
||||
**Сценария три, а точка входа одна.** Какой из них идёт, решает **скилл**,
|
||||
прочитав постановку, а не человек до вызова: «есть ли у задачи очевидный способ
|
||||
решения» и «меняется ли то, что записано в спеке» видно после чтения записи, и
|
||||
требовать этих суждений от вызывающего значит требовать их раньше, чем они
|
||||
возможны.
|
||||
|
||||
| Сценарий | Когда | Чем кончается |
|
||||
| --- | --- | --- |
|
||||
| **решение** | способ известен, меняется поведение | код, ревью, архив, коммит, закрытие |
|
||||
| **обслуживание** | способ известен, спека не меняется: тип `chore` | правка, ревью, синк, коммит, закрытие |
|
||||
| **разведка** | способа нет: тип `research`, сырая идея, мутная постановка | ответ в документах, задачи, коммит, закрытие |
|
||||
|
||||
Ход каждого сценария живёт своим справочником: **решение** —
|
||||
[references/solve.md](references/solve.md), **обслуживание** —
|
||||
[references/maintain.md](references/maintain.md), **разведка** —
|
||||
[references/research.md](references/research.md). Здесь только общее: вход,
|
||||
развилка, правила, которые не зависят от сценария. Сценарии лежат порознь и
|
||||
одинаково, потому что привилегированного среди них нет: тот, что жил бы прямо
|
||||
здесь, читался бы как основной, а прочие — как оговорка.
|
||||
|
||||
## Предпосылки
|
||||
|
||||
- **OpenSpec и скиллы `opsx:*` — жёсткая предпосылка сценария решения**, а не
|
||||
опция. На них стоят его шаги 2, 6 и 8, проход `review-specs` и ревью дизайна
|
||||
(они завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
||||
подключай OpenSpec, а не вырождай цикл сценария; почему ветка деградации здесь
|
||||
не
|
||||
пишется, сказано в `av-dev:code-review`, раздел «Предпосылки», и дом у этого
|
||||
довода там. Заводить руками не надо: каталог и настройку в `config.yaml`
|
||||
делает скилл `av-dev:code-openspec`. **Сценариям разведки и обслуживания
|
||||
OpenSpec не нужен** — они не заводят change; `opsx:explore` берётся разведкой,
|
||||
если плагин есть.
|
||||
- **Проектные копии этих скиллов и агентов удаляются при установке плагина**
|
||||
(`.claude/skills/` — голые имена `resolve`, `review`, а у проектов прошлого
|
||||
поколения ещё `task-pipeline`, `review-pipeline`, `task-batch`, и с префиксом
|
||||
проекта: `<проект>-task-pipeline`, `<проект>-review-pipeline`;
|
||||
`.claude/agents/<проект>-review-*.md`). Две копии одного скилла расходятся, и
|
||||
побеждает та, что короче названа.
|
||||
|
||||
### Обращение к соседним плагинам
|
||||
|
||||
**Копия.** Дом — `shared/plugin-boundary.md` в репозитории плагинов: правило
|
||||
общее для всех, кто зовёт чужое, и ни один плагин им не владеет. Правится дом, а
|
||||
не этот файл.
|
||||
|
||||
<!-- копия: граница-плагинов из av-dev/shared/plugin-boundary.md -->
|
||||
|
||||
Плагины `av-dev` ставятся порознь, и ни один не вправе считать, что сосед на
|
||||
месте.
|
||||
|
||||
**Чужой скилл зовётся полным именем** — `av-dev:doc-canon`, `av-dev:task-track`,
|
||||
`av-dev:code-review`. Короткое имя может разрешиться в устаревшую проектную копию
|
||||
из `.claude/skills/`, и подмены не будет видно ни в докладе, ни в поведении.
|
||||
|
||||
**Путь в дерево чужого плагина не пишется никогда.** `$CLAUDE_PLUGIN_ROOT` ведёт
|
||||
только в свой плагин; вычисленный от него путь к соседу либо не откроется, либо
|
||||
откроет чужую установку. Нужен чужой справочник — зови владеющий им скилл, он
|
||||
прочитает его сам.
|
||||
|
||||
**Вызов не разрешился — плагина в проекте нет.** Это исход, а не поломка: назови
|
||||
строкой доклада, чего теперь не делает никто, и продолжай работу. Молчать нельзя,
|
||||
пропуск неотличим от сделанного; выдумывать обходной путь нельзя тоже.
|
||||
|
||||
**Присутствие узнаётся вызовом или следом в проекте, но не объявлением.** Перечня
|
||||
установленных плагинов проект не ведёт — он разошёлся бы с действительностью
|
||||
молча. Что сосед здесь работал, видно по заведённому им файлу: `docs/.docs.json` —
|
||||
канон, `<каталог задач>/.tasks.json` — задачи, `openspec/config.yaml` — конвейер.
|
||||
Имя файла — имя плагина, который его завёл, и держит он в том числе версию своего
|
||||
формата: у канона документов и у каталога задач они свои и двигаются порознь.
|
||||
|
||||
<!-- /копия: граница-плагинов -->
|
||||
|
||||
Скилл зовёт `av-dev:code-review`, `av-dev:doc-sync` и
|
||||
`av-dev:task-track`. Чем оборачивается отсутствие каждого — на самих шагах и в
|
||||
разделе «Границы».
|
||||
|
||||
Перед стартом прочитай `CLAUDE.md` проекта и то, на что он ссылается, если ещё
|
||||
не в контексте. Проектные факты, нужные ревью — инварианты, семантика гейта,
|
||||
объёмы, модель угроз, прецеденты, — живут в **документах канона** `av-dev-docs`;
|
||||
карта «что где» — `references/project-facts.md` конвейера ревью.
|
||||
|
||||
**Документов канона нет — проект к нему не приведён.** Скажи это строкой и
|
||||
предложи скилл `av-dev:doc-canon`: одна операция на проект против поразрядной
|
||||
деградации на каждой задаче. Работу при этом не останавливай.
|
||||
|
||||
## Вход
|
||||
|
||||
Задача задаётся **путём к файлу, именем файла, слагом или просто текстом**.
|
||||
Ничего из этого не задано — попроси у вызывающего и остановись; сам в беклог не
|
||||
лезь и приоритеты не интерпретируй: что делать дальше, решает не этот скилл.
|
||||
|
||||
**Запись из каталога сперва проверяется на готовность, и проверяет её машина.**
|
||||
Вызови Skill `av-dev:task-track` и попроси прогнать `ready <слаг>`: он смотрит
|
||||
тип, цель у `feature`, пустой ли раздел вопросов и собраны ли разделы схемы
|
||||
типа. Судить это глазами нельзя — ровно тот случай, где машина дешевле и точнее,
|
||||
а цена ошибки отложенная: недостающие критерии приёмки обнаружатся на приёмке,
|
||||
когда сверять уже не с чем.
|
||||
|
||||
**`ready` отказал — это исход, а не препятствие для тебя.** Скажи, чего не
|
||||
хватает, и остановись: дописывать чужую запись за автора не твоя работа. Исход —
|
||||
«не доведена», с названной причиной.
|
||||
|
||||
**Отказ `ready` сценарий не выбирает.** Запись `research` без раздела «Вопрос»
|
||||
(сырьё) — отказ и здесь: у неё нет вопроса, и разведывать нечего.
|
||||
|
||||
Плагина `av-dev-tasks` в проекте нет или задача пришла текстом — прогонять
|
||||
нечего. Тогда прочитай постановку сам и скажи строкой, что готовность машиной не
|
||||
проверялась; работу при этом не останавливай.
|
||||
|
||||
## Развилка: какой сценарий
|
||||
|
||||
Она в два вопроса, и оба стоят до всякой работы.
|
||||
|
||||
**Первый: есть ли у задачи один очевидный способ решения?**
|
||||
|
||||
- **нет** — тип `research`, сырая идея, новое и незнакомое, мутная постановка,
|
||||
два подхода с разной ценой. **Сценарий разведки** —
|
||||
[references/research.md](references/research.md);
|
||||
- **есть** — что делать, понятно; спорно только как. Тогда второй вопрос.
|
||||
|
||||
**Второй: меняется ли то, что записано в `openspec/specs/`?**
|
||||
|
||||
- **меняется** — появляется или правится поведение. **Сценарий решения** —
|
||||
[references/solve.md](references/solve.md);
|
||||
- **не меняется** — тулчейн и сборка, зависимости, гит-хуки и шаги гейта,
|
||||
перенос, чистка. **Сценарий обслуживания** —
|
||||
[references/maintain.md](references/maintain.md).
|
||||
|
||||
**Второй вопрос решается связкой из двух признаков, и оба обязательны:** тип
|
||||
записи предлагает (`chore`, реже `fix`, возвращающий поведение к уже
|
||||
записанному), а отсутствие дельт подтверждает. Тип объявляет автор и может
|
||||
ошибиться; отсутствие дельт — твоё суждение и принимается только вместе с типом.
|
||||
Признаки разошлись — это стоп, а не выбор: скажи, что тип и предмет работы не
|
||||
сходятся, и остановись. Подробно — [maintain.md](references/maintain.md), раздел
|
||||
«Признак — связка, а не одно условие».
|
||||
|
||||
**Признак не в объёме работы, и это относится к обоим вопросам.** Крупная задача
|
||||
с очевидным способом идёт в решение; маленькая, но незнакомая — в разведку;
|
||||
однострочная правка, меняющая поведение, идёт полным циклом решения, а не
|
||||
обслуживанием. Путь, выбираемый по самооценке размера, — самый дешёвый способ
|
||||
«ускориться» и самый дорогой по последствиям. Тип `research` в разведку идёт
|
||||
всегда: её исход знание, а не изменение системы.
|
||||
|
||||
**Назови выбранный сценарий вслух первой репликой** — одной строкой, с причиной.
|
||||
Молча выбранный сценарий человек обнаруживает по тому, что работа пошла не туда,
|
||||
и обнаруживает поздно.
|
||||
|
||||
### Сценарий выбирается один раз
|
||||
|
||||
**Смена сценария по ходу — событие, а не тихий поворот**, и каждая смена
|
||||
устроена по-своему:
|
||||
|
||||
- **решение → разведка**: обнаружилось, что очевидного способа нет. Это **стоп**
|
||||
с исходом «нужна разведка»: назови, что именно неясно, и не продолжай.
|
||||
Кода к этому моменту не написано, и писать его «пока разбираемся» нельзя;
|
||||
- **обслуживание → решение**: нашлась дельта-спека, то есть поведение всё-таки
|
||||
меняется. Задача не сломалась — она **оказалась шире своего типа**, и стоп
|
||||
здесь несёт человеку выбор: назови тип, которым она оказалась (`fix` —
|
||||
расходится с заявленным, `feature` — снаружи появляется то, чего не было),
|
||||
объясни простым языком, что нашлось, и дай два решения — **переформулировать
|
||||
запись и решать процессом того типа следующим прогоном** либо **прекратить
|
||||
работу**. Третьего — «доделать как обслуживание» — нет. Исход в обоих случаях
|
||||
«меняется спека»; сделанное остаётся в рабочем дереве незакоммиченным, тип
|
||||
меняет `av-dev:task-track` и только после ответа. Подробно —
|
||||
[maintain.md](references/maintain.md), раздел «Дельта нашлась по ходу»;
|
||||
- **обслуживание → разведка**: форма правки неизвестна (мажорное обновление,
|
||||
смена сборщика). **Стоп** с исходом «нужна разведка», по тому же основанию,
|
||||
что и у решения;
|
||||
- **разведка → решение или обслуживание**: способ выбран на чекпоинте вариантов.
|
||||
Разведка **всё равно доводится до конца** — ответ записан, задачи уточнены,
|
||||
коммит сделан, — и работа идёт **следующим прогоном**, который запускает
|
||||
человек.
|
||||
|
||||
Обратной смены «решение → обслуживание» нет: задача, заведшая change, доводится
|
||||
циклом решения. Дельта-спеки, оказавшиеся пустыми, — находка ревью дизайна о
|
||||
самой постановке, а не повод свернуть на короткий путь из середины длинного.
|
||||
|
||||
**Соблазн «разведаю по ходу» живёт именно здесь**, и он дорог тем, что выглядит
|
||||
экономией одного прогона. Разведка внутри решения не имеет своего чекпоинта:
|
||||
выбор делается тем, кто уже начал писать, и человек видит его только в
|
||||
объяснении, где обсуждать выбор поздно. Ровно за это сценарии и разведены — не за
|
||||
то, что это разные работы, а за то, что у них разные моменты для человека.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["вход: файл, слаг или текст"]
|
||||
ready["ready: готовность записи<br/>av-dev:task-track"]
|
||||
fork{"есть очевидный<br/>способ решения?"}
|
||||
fork2{"меняется ли<br/>спека?"}
|
||||
solve["сценарий решения<br/>references/solve.md<br/>код, ревью, архив, коммит"]
|
||||
main["сценарий обслуживания<br/>references/maintain.md<br/>правка, ревью, синк, коммит"]
|
||||
res["сценарий разведки<br/>references/research.md<br/>ответ в документы и задачи"]
|
||||
|
||||
in --> ready --> fork
|
||||
fork -->|"да"| fork2
|
||||
fork -->|"нет"| res
|
||||
fork2 -->|"да"| solve
|
||||
fork2 -->|"нет: тип chore"| main
|
||||
solve -.->|"способа всё же нет:<br/>стоп, кода не написано"| res
|
||||
main -.->|"нашлась дельта: стоп,<br/>тип на fix или feature,<br/>следующим прогоном"| solve
|
||||
main -.->|"форма неизвестна:<br/>стоп"| res
|
||||
res -.->|"способ выбран:<br/>следующим прогоном,<br/>зовёт человек"| solve
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание сценариев в их справочниках, и при расхождении
|
||||
прав справочник.
|
||||
|
||||
## Автономность и плановый стоп
|
||||
|
||||
**У двух сценариев ровно один плановый стоп**, и стоят они в разных местах:
|
||||
у решения — объяснение после ревью дизайна, у разведки — варианты до первого
|
||||
написанного требования. Правило вокруг них общее.
|
||||
|
||||
**У обслуживания планового стопа нет вовсе, и это следствие, а не поблажка.**
|
||||
Один стоп с ожиданием ответа у него всё же есть — по найденной дельта-спеке, — но
|
||||
плановым он не является: через него проходят только те прогоны, где задача
|
||||
оказалась не тем, чем объявлена.
|
||||
Чекпоинт объясняет человеку **выбор**, а у обслуживания выбора нет по
|
||||
построению: что делать, сказано в записи, и объяснение свелось бы к пересказу
|
||||
задачи её же автору. Стоп, на котором нечего решать, вырождается в обряд
|
||||
одобрения и обесценивает те стопы, где решать есть что. Правило необратимого
|
||||
(ниже) действует там полностью и срабатывает чаще, чем в двух других сценариях:
|
||||
выкладка, токены, хуки и чужие данные — обычное содержимое задач обслуживания.
|
||||
|
||||
**Вокруг чекпоинта умолчание прежнее — делать, а не спрашивать.** Чекпоинт не
|
||||
отменяет автономность, он даёт развилкам плановое место, куда копиться.
|
||||
|
||||
Разрез простой:
|
||||
|
||||
- развилка найдена **до** чекпоинта — она его и ждёт. Не спрашивай отдельно:
|
||||
чекпоинт рядом и стоит дёшево, а три вопроса подряд стоят дороже одного
|
||||
разговора;
|
||||
- развилка найдена **после** чекпоинта — старое правило: **запиши вопрос и доведи
|
||||
остаток**, не останавливаясь.
|
||||
|
||||
Запись вопроса устроена так:
|
||||
|
||||
1. **Запиши там, где проект держит вопросы** (секция беклога, файл задачи,
|
||||
трекер — это знает проект). Проект не сказал, куда, — отдельной секцией
|
||||
`Вопросы` в своём докладе, и это тоже исход. Тело отвечает на три вещи: **что
|
||||
именно решить**, **какие есть варианты и цена каждого**, **что стоит, пока
|
||||
решения нет**. Плюс твоя рекомендация — человек чаще соглашается, чем выбирает
|
||||
заново, и готовое суждение экономит ему весь контекст.
|
||||
2. **Переформулируй задачу на остаток** — то, что делается без этого решения.
|
||||
Назови границу: докуда доводим сейчас.
|
||||
3. Доведи остаток до конца и закоммить. Задача не «висит на вопросе», она сделана
|
||||
в объявленных границах. В разведке остаток — это ответ в объявленных рамках:
|
||||
что успели узнать, где остановились и почему.
|
||||
|
||||
**Что остатком не является — правило живёт не здесь.** Канонический текст с обеими
|
||||
оговорками — в плагине `av-dev-tasks`, скилл `av-dev:task-groom`, раздел
|
||||
`## Вопрос, блокер, необратимое`, подраздел «Отличать вопрос от застревания».
|
||||
Правило принадлежит управлению задачами, потому что решает **сделана задача или
|
||||
вышла**, — это исход планирования, а не исполнения. **Ссылайся, не
|
||||
пересказывай:** копия, заведённая здесь, уже однажды разошлась с оригиналом и
|
||||
потеряла из перечня самое необратимое — запись **наружу**.
|
||||
|
||||
Коротко, чтобы знать, когда идти читать: остаток проверяется двумя порогами —
|
||||
**материализация нерешённого** (запись состояния, зависящего от неотвеченного
|
||||
вопроса) и **пол по пользе** (из остатка пропала польза, названная в постановке).
|
||||
Оба порога — стоп: первый поднимает решение до начала записи, второй даёт исход
|
||||
«не доведена».
|
||||
|
||||
Плагин `av-dev-tasks` не подключён — правило не отменяется, а становится
|
||||
осторожнее: прежде чем записать зависящее от нерешённого куда бы то ни было —
|
||||
в хранилище, в журнал, в витрину или наружу, — спрашивай человека.
|
||||
|
||||
Нет полезного остатка — задача заканчивается исходом «не доведена», вопрос
|
||||
записан, ничего не коммитится наполовину.
|
||||
|
||||
### Когда спрашивать вне чекпоинта
|
||||
|
||||
По другому основанию — не «сложное решение», а **необратимое действие**:
|
||||
|
||||
- деплой, выкладка наружу, смена публичного адреса или токенов;
|
||||
- удаление или перезапись рабочих данных, включая подрезку архивов;
|
||||
- всё, что уходит за пределы машины.
|
||||
|
||||
Здесь ошибка не откатывается коммитом, поэтому спрашиваем даже когда решение
|
||||
кажется очевидным.
|
||||
|
||||
## Границы: чем этот скилл не владеет
|
||||
|
||||
- **Беклогом, целями и приоритетами.** Задача приходит извне. Скилл её не
|
||||
выбирает, не приоритизирует, не заводит и не переоценивает.
|
||||
- **Форматом задач и документов.** Индексы и документы канона руками не правятся,
|
||||
путь к чужому скрипту не выдумывается: этим владеют `av-dev:task-track` и
|
||||
`av-dev:doc-sync`. Закрытие — работа этого скилла, и это осознанное решение с
|
||||
названной ценой: **приёмщик и исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на
|
||||
груминге (`av-dev:task-groom`) возвращает задачу `reopen` с причиной, а доклад
|
||||
по критериям приёмки становится единственным, по чему приёмка вообще возможна.
|
||||
- **Определением ценности.** «Нужна ли эта функциональность» — не вопрос этого
|
||||
скилла ни на одном шаге и ни в одном сценарии. Чекпоинт решения спрашивает «так
|
||||
ли решаем», чекпоинт разведки — «каким из способов», но не «надо ли».
|
||||
|
||||
Что не принадлежит **отдельному сценарию**, названо у него же: урожай ревью и
|
||||
выбор способа — в [solve.md](references/solve.md), изменение поведения и нарезка
|
||||
пачки — в [maintain.md](references/maintain.md), код и приоритет — в
|
||||
[research.md](references/research.md).
|
||||
|
||||
## Наблюдаемые исходы
|
||||
|
||||
**У каждого сценария их четыре**, и живут они у сценария:
|
||||
[решение](references/solve.md) — сделана, не доведена, оказалась крупнее задачи,
|
||||
нужна разведка; [обслуживание](references/maintain.md) — сделана, не доведена,
|
||||
меняется спека, нужна разведка; [разведка](references/research.md) — способ
|
||||
выбран, знание записано, отказ, не доведена.
|
||||
|
||||
Общего исхода нет намеренно. «Сделана» у решения и «знание записано» у разведки —
|
||||
разные вещи с разной приёмкой, и слово, накрывающее оба, скрывало бы именно то,
|
||||
чем прогон кончился. «Сделана» у решения и у обслуживания совпадает словом, но не
|
||||
определением: у первого в него входит пройденный чекпоинт и заархивированный
|
||||
change, у второго — сверенный состав гейта и синк.
|
||||
|
||||
## Доклад
|
||||
|
||||
Ядро общее, и в нём обязательно:
|
||||
|
||||
- **какой сценарий шёл** — решение, обслуживание или разведка, — и почему выбран
|
||||
он;
|
||||
- **исход** одним из четырёх слов своего сценария и, если он не благополучный,
|
||||
чем ограничен результат;
|
||||
- что сделано, какие вопросы записаны и куда;
|
||||
- чего проверить или узнать **не удалось**.
|
||||
|
||||
Сверх ядра каждый сценарий добавляет своё: [solve.md](references/solve.md) —
|
||||
чекпоинт, change, критерии приёмки, урожай и границы покрытия;
|
||||
[maintain.md](references/maintain.md) — чем подтверждён признак, состав гейта до
|
||||
и после, критерии приёмки, урожай и границы покрытия;
|
||||
[research.md](references/research.md) — вопрос и ответ, адреса записи, заведённые
|
||||
задачи, рамки.
|
||||
|
||||
## Тонкости
|
||||
|
||||
- **Не завязывайся на основную ветку и корень репозитория.** Скилл работает в
|
||||
текущем worktree и на текущей ветке: не делай `git checkout`/`switch`, не
|
||||
создавай веток, не пушь.
|
||||
- Прогон проходит **не больше одного** чекпоинта, и это норма, а не упрощение.
|
||||
Два стопа за одну задачу — цена незнания способа, и платится она двумя
|
||||
прогонами, а не одним длинным. У обслуживания чекпоинта нет ни одного, и это
|
||||
тоже норма: там нечего решать.
|
||||
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
|
||||
подтверждать механику: чекпоинт — единственное место, где ждут ответа, а в
|
||||
обслуживании такого места нет вовсе.
|
||||
- **Сценарий назван вслух — значит, его можно оспорить.** Человек, увидевший в
|
||||
первой реплике «иду разведкой, потому что способа не видно», поправит выбор
|
||||
одной фразой; молча выбранный сценарий он поправит через полчаса работы.
|
||||
@@ -0,0 +1,410 @@
|
||||
# Сценарий «обслуживание»
|
||||
|
||||
Способ решения известен, а **того, что нормирует спека, задача не трогает**:
|
||||
тулчейн и сборка, зависимости, гит-хуки и шаги гейта, перенос и чистка. Сценарий
|
||||
**пишет код**, но не заводит change и не пишет требований. Исход — работающая
|
||||
оснастка и синхронная ей документация.
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
ход; общее для всех трёх сценариев — вход, обращение к соседним плагинам, правило
|
||||
записанного вопроса, правило необратимого — живёт в SKILL.md и тут не
|
||||
пересказывается.
|
||||
|
||||
## Почему цикл SDD здесь не урезан, а остался без входа
|
||||
|
||||
Это не поблажка по цене, и называть сценарий «коротким путём для мелких задач»
|
||||
нельзя: путь, выбираемый по самооценке размера, и есть тот самый дешёвый способ
|
||||
«ускориться», против которого написана вся защита сценария решения.
|
||||
|
||||
**У обслуживания нет дельта-спек по построению.** Тип `chore` определён через
|
||||
«наблюдаемое поведение не меняется», а на дельтах стоит весь цикл: `propose`
|
||||
их порождает, разметка выведена **из них**, `review-specs` сверяет **с ними**,
|
||||
объяснение чекпоинта собирается из `proposal.md` и `design.md`, `archive` вливает
|
||||
их в актуальные спеки. Change без дельт — пустой артефакт, который потом надо
|
||||
архивировать, и разметчик по нему назовёт не те темы.
|
||||
|
||||
Шаги цикла здесь не пропущены — **им нечего обрабатывать**. Отсюда и состав
|
||||
сценария: выпали ровно те шаги, у которых нет предмета, и не выпал ни один из
|
||||
тех, у которых он есть.
|
||||
|
||||
## Признак — связка, а не одно условие
|
||||
|
||||
Сценарий выбирается двумя проверками сразу, и обе обязательны:
|
||||
|
||||
1. **тип записи предлагает** — `chore`, реже `fix`, чьё исправление возвращает
|
||||
поведение к уже записанному в спеке;
|
||||
2. **отсутствие дельт подтверждает** — прочитав постановку, ты не находишь
|
||||
требования, которое пришлось бы добавить, изменить или снять.
|
||||
|
||||
Один признак без второго не выбирает сценарий. Тип объявляет автор записи, и он
|
||||
может ошибиться в обе стороны; отсутствие дельт — суждение исполнителя, и оно
|
||||
принимается только тогда, когда согласуется с объявленным типом. Расхождение
|
||||
двух признаков — это не развилка, а стоп: скажи, что тип и предмет работы
|
||||
разошлись, и остановись.
|
||||
|
||||
**Имя сценария не равно имени типа, и это намеренно.** `fix` без дельта-спеки
|
||||
идёт сюда законно — поведение разошлось с **заявленным**, значит заявленное уже
|
||||
записано, и менять спеку не нужно. Сценарий, названный именем типа, такую задачу
|
||||
либо отправил бы в полный цикл ради пустого change, либо принял бы как
|
||||
исключение, а исключения не исполняются.
|
||||
|
||||
## Дельта нашлась по ходу — стоп, и у него свой порядок
|
||||
|
||||
Признак тот же, что на шаге 7 сценария решения: **меняется ли то, что записано в
|
||||
`openspec/specs/`**. Обнаружилось, что меняется, — работа перестала быть
|
||||
обслуживанием в ту же секунду, и продолжать её нельзя: коммит обслуживания
|
||||
заявляет «поведение не менялось», а оно меняется.
|
||||
|
||||
**Задача при этом не сломалась — она оказалась шире своего типа.** Поэтому стоп
|
||||
здесь не «бросить и доложить», а три шага по порядку.
|
||||
|
||||
**1. Назови тип, которым задача оказалась.** Разрез тот же, по которому типы и
|
||||
разведены:
|
||||
|
||||
- **`fix`** — поведение расходится с **заявленным**: спека уже описывает верное,
|
||||
и правка возвращает систему к записанному;
|
||||
- **`feature`** — снаружи появляется то, чего не было: спеке нужно новое
|
||||
требование.
|
||||
|
||||
Тип называется прямо и с причиной. «Нужно менять спеки» без имени типа
|
||||
перекладывает классификацию на человека в тот момент, когда весь материал для неё
|
||||
у тебя.
|
||||
|
||||
**2. Объясни человеку простым языком.** Экран текста, не больше:
|
||||
|
||||
- **что просили сделать** — одной фразой из записи;
|
||||
- **что нашлось** — какое поведение меняется, словами домена, а не именами
|
||||
файлов и функций;
|
||||
- **почему это перестало быть обслуживанием** — одной фразой: у обслуживания
|
||||
поведение не меняется по определению;
|
||||
- **чем задача становится** — `fix` или `feature`, с причиной из разреза выше;
|
||||
- **что уже сделано** и что из этого лежит в рабочем дереве.
|
||||
|
||||
Проверка на простой язык та же, что у чекпоинтов двух других сценариев: **в
|
||||
тексте нет `SHALL`, нет имён файлов и функций там, где вещь называется
|
||||
по-русски, и нет слов, которых нет в паспорте проекта.**
|
||||
|
||||
**3. Дай два решения и жди ответа.** Их ровно два, и оба законны:
|
||||
|
||||
- **переформулировать запись** — тип меняется на названный, и дальше задача идёт
|
||||
**процессом своего типа**: сценарием решения, следующим прогоном. Формат записи
|
||||
правит `av-dev:task-track`, а не ты: у нового типа своя схема разделов, и
|
||||
готовность её проверит `ready` — той же машиной, что и на входе. Прогон
|
||||
обслуживания на этом кончается, исход — «меняется спека»;
|
||||
- **прекратить работу** — человек не готов расширять задачу сейчас. Исход тот
|
||||
же, запись остаётся как была, вопрос записывается там, где проект держит
|
||||
вопросы.
|
||||
|
||||
**Третьего решения — «доделать как обслуживание» — нет.** Оно и есть то самое
|
||||
молчаливое изменение поведения, против которого стоит весь разрез: под коммитом,
|
||||
заявляющим «поменяли оснастку», уехала бы правка, не прошедшая ни ревью дизайна,
|
||||
ни чекпоинта, и не оставившая следа в спеках.
|
||||
|
||||
**Сделанное не выбрасывается ни при каком из двух решений.** Оно остаётся в
|
||||
рабочем дереве незакоммиченным: при переформулировке уезжает в change следующим
|
||||
прогоном, при отказе — человек решает сам, откатить или оставить. Коммитить его
|
||||
сообщением про обслуживание нельзя.
|
||||
|
||||
**Прогон, дошедший до этого стопа, стоит дороже обычного** — и это довод за
|
||||
проверку признака на шаге 1, а не после написанного кода.
|
||||
|
||||
## OpenSpec здесь не предпосылка
|
||||
|
||||
Как и разведке, обслуживанию OpenSpec не нужен: оно не заводит change, не пишет
|
||||
дельта-спек и не архивирует. Ни один из проходов его плана ревью на дельта-спеки
|
||||
не завязан — это сказано и в `av-dev:code-review`, раздел «Прогон без change».
|
||||
Каталога в проекте нет — обслуживание идёт целиком, и деградацией это не
|
||||
является.
|
||||
|
||||
## Планового стопа у этого сценария нет
|
||||
|
||||
**И это следствие, а не упрощение.** Чекпоинт решения объясняет человеку
|
||||
**выбор**: в чём проблема, как решаем, чем рискуем. У обслуживания выбора нет по
|
||||
построению — что делать, сказано в записи, а критерии приёмки у него самые
|
||||
дешёвые из всех типов: команда, которая раньше падала или требовала трёх шагов.
|
||||
Объяснение свелось бы к пересказу задачи её же автору. Стоп, на котором нечего
|
||||
решать, вырождается в обряд одобрения и обесценивает те стопы, где решать есть
|
||||
что.
|
||||
|
||||
**Место, где ответа всё же ждут, одно, и плановым оно не является** — стоп по
|
||||
найденной дельте (раздел «Дельта нашлась по ходу»). Через него проходят не все
|
||||
прогоны, а только те, где задача оказалась не тем, чем объявлена.
|
||||
|
||||
**Правило необратимого при этом действует полностью** (SKILL.md, «Когда
|
||||
спрашивать вне чекпоинта»), и здесь оно опаснее, чем кажется. Единственный
|
||||
сценарий без планового стопа — ровно тот, чья работа чаще прочих лезет в
|
||||
выкладку, в токены, в хуки и в чужие данные. Правка оснастки выглядит безобидной
|
||||
до момента, когда её уже не откатить.
|
||||
|
||||
## Ход работы
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["сценарий выбран: обслуживание"]
|
||||
s1["1. прочитать задачу<br/>критерии приёмки и границы"]
|
||||
s2["2. сделать правку<br/>гейт тронут — сверить состав, не цвет"]
|
||||
s3["3. гейт проекта до зелёного"]
|
||||
s4["4. ревью фиксированным планом<br/>av-dev:code-review, без change"]
|
||||
s5["5. синк документации — av-dev:doc-sync"]
|
||||
s6["6. коммит работы — av-dev-git:commit"]
|
||||
s7["7. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
out["исход назван"]
|
||||
|
||||
in --> s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> out
|
||||
s1 -.->|"форма правки неизвестна"| stop1["стоп: нужна разведка"]
|
||||
s2 -.->|"нашлась дельта-спека"| stop2["стоп: назвать тип,<br/>объяснить, дать два решения"]
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при расхождении
|
||||
прав текст.
|
||||
|
||||
## Наблюдаемые исходы сценария
|
||||
|
||||
Четыре, и каждый обязан быть назван в докладе прямо:
|
||||
|
||||
- **сделана** — определение сделанного выполнено целиком;
|
||||
- **не доведена** — с причиной и с записанным вопросом; названо, что именно
|
||||
сделано и до какой границы;
|
||||
- **меняется спека** — работа оказалась шире своего типа. Стоп с объяснением и
|
||||
двумя решениями человека: переформулировать запись в `fix` или `feature` и
|
||||
решать её процессом того типа следующим прогоном — либо прекратить. Сделанное
|
||||
остаётся в рабочем дереве незакоммиченным. Доклад называет **оба**: какой тип
|
||||
предложен и что человек выбрал;
|
||||
- **нужна разведка** — форма правки неизвестна (мажорное обновление, смена
|
||||
сборщика, переезд гейта на другой инструмент) **или сработал триггер ADR**:
|
||||
дорогой откат, намеренный отказ от очевидного подхода, пересмотр прежнего
|
||||
решения. Стоп с названной причиной, разведка идёт следующим прогоном.
|
||||
|
||||
**Последний исход — не редкость, и его стоит ждать.** Незнакомое обслуживание —
|
||||
это выбор подхода с ценой и с тем, что становится невозможным, — предмет чекпоинта
|
||||
вариантов, а не работы без стопа. И там же решение получает законный источник для
|
||||
ADR: список источников канон закрыл двумя — архивный `design.md` и записка
|
||||
разведки, — а обслуживание не производит ни того ни другого.
|
||||
|
||||
## Определение сделанного
|
||||
|
||||
Задача сделана, когда верно всё:
|
||||
|
||||
1. гейт проекта зелёный, и **если правка трогала сам гейт — сверен его состав**,
|
||||
а не только цвет;
|
||||
2. ревью проведено фиксированным планом сценария, исход назван по каждой теме
|
||||
плана, а темы, которых в плане нет, названы в границах покрытия;
|
||||
3. **документация синхронизирована с принуждённым отрицанием** — каждый документ
|
||||
канона получил строку;
|
||||
4. коммит сделан в текущую ветку;
|
||||
5. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
|
||||
оракул и наблюдаемый исход.** Это доклад приёмщику, а не отметка «принято»:
|
||||
исполнитель и приёмщик здесь совпали, и правило то же, что в решении.
|
||||
|
||||
## Шаги
|
||||
|
||||
### 1. Прочитать задачу
|
||||
|
||||
Прочитай запись. У `chore` обязательны два раздела, и оба нужны тебе прямо
|
||||
сейчас: **«Затрагивает»** — границы, которые у обслуживания часто не в коде
|
||||
(конфиг и его образцы, версия зависимости, команда сборки, файл CI), и
|
||||
**«Критерии приёмки»** — с оракулами.
|
||||
|
||||
Здесь же обе проверки признака: тип предлагает, отсутствие дельт подтверждает
|
||||
(раздел «Признак — связка»). И здесь же — проверка на незнакомое: если форма
|
||||
правки не известна до начала, а нащупывается по ходу, объявляй исход **нужна
|
||||
разведка** и не начинай.
|
||||
|
||||
**Проверка на «заодно».** Обслуживание любит склеиваться в пачку — обновить
|
||||
зависимости, переписать сборку и убрать мёртвый код одной задачей. Не мерджится
|
||||
порознь — это несколько задач: объявляй исход **не доведена** с причиной «задача
|
||||
не одна» и останавливайся. Нарезкой владеет `av-dev:task-track`, а не ты, и
|
||||
делать её по ходу нельзя — получится один коммит, в котором обновление
|
||||
зависимости не отделить от чистки.
|
||||
|
||||
### 2. Сделать правку
|
||||
|
||||
Код и конфиги — по конвенциям проекта. Правка по размеру задачи: чинится названное в записи, соседнее не улучшается
|
||||
заодно.
|
||||
|
||||
**Гейт правится — сверь состав, а не цвет.** Красный, ставший зелёным, виден
|
||||
сразу; убыли проверок гейт не покажет — он зелёный и до, и после. Это самая
|
||||
дорогая из возможных правок оснастки: молча выключено то, чем проверяется всё
|
||||
остальное. Состав проверок и способ его снять — **дело проекта**: он объявляет
|
||||
их семантикой гейта в `CLAUDE.md`. Снимай исходное состояние **до** правки, по
|
||||
тому, как проект это описал.
|
||||
|
||||
**Проект состав не описал — скажи строкой доклада, что сверен только цвет.**
|
||||
Обходного пути не выдумывай: угаданный состав хуже отсутствующего, потому что
|
||||
читается как сверенный. Это же строка и повод — предложить проекту дописать слот
|
||||
в `CLAUDE.md`.
|
||||
|
||||
### 3. Гейт до зелёного
|
||||
|
||||
Прогони гейт и добейся зелёного — он же условие следующего шага: пока гейт
|
||||
красный, проходы с мнением не запускаются.
|
||||
|
||||
**Поведенческая верификация здесь другая, чем в решении.** Проверяется не новое
|
||||
поведение, а то, что прежнее не поехало: команда из `CLAUDE.md` поднимается, шаг
|
||||
сборки отрабатывает, хук ставится на чистом клоне. Правка, которую нельзя
|
||||
проверить ничем, кроме «у меня локально работает», называется в докладе строкой.
|
||||
|
||||
### 4. Ревью — план фиксирован сценарием
|
||||
|
||||
Вызови Skill **`av-dev:code-review`**, дав базу диффа, режим и **план сценария**.
|
||||
Change ты не передаёшь — его нет.
|
||||
|
||||
**Разметчик здесь не зовётся, и это правило, а не пропуск.** Обе оси, по которым
|
||||
он судит, у обслуживания не определены: размер он меряет по `proposal.md`,
|
||||
`design.md`, `tasks.md` и дельта-спекам, а незнакомость — по форме решения,
|
||||
которой здесь нет (незнакомое ушло в разведку шагом 1). Разметчик без своего
|
||||
корпуса вернул бы метку, выведенную из ничего.
|
||||
|
||||
Поэтому план у сценария **свой и постоянный**, и глубину он называет сам —
|
||||
проходы берут её из метки, а метки здесь нет:
|
||||
|
||||
| Тема | Дом | Кто закрывает | Глубина и вход | Когда |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `autotests` | `CLAUDE.md`, семантика гейта | `review-autotests` | как обычно: гейт запускается целиком | всегда |
|
||||
| `operations` | `architecture.*`, раздел эксплуатации | `review-basics` | **сверка**: дом темы против диффа, потолок 2 | всегда |
|
||||
| `conventions` + технический разбор | `conventions.*` | `review-code` | вход `small`: только индекс конвенций; потолки 3 технических и 2 конвенционных; **третья половина включена** — сверка с инвариантами `CLAUDE.md`, потолок 1 | дифф трогает код, а не только оснастку |
|
||||
|
||||
**Глубина названа в плане потому, что иначе её неоткуда взять.** Вход и потолки
|
||||
`review-code` заданы меткой, у `review-basics` меткой задана и сама возможность
|
||||
запуска; на прогоне без метки оба взяли бы их наугад — то есть по-разному от
|
||||
прогона к прогону, и молча.
|
||||
|
||||
**Третья половина `review-code` включена намеренно.** В конвейере она живёт при
|
||||
метке `small`, где приёмник тем не запускается, и сверяет дифф с записанными
|
||||
инвариантами `CLAUDE.md` по темам `security`, `operations` и `architecture`.
|
||||
Здесь у неё та же работа: без неё `security` не смотрит вообще никто.
|
||||
|
||||
Триаж обязателен, как и на всяком прогоне: он единственный сток и единственный,
|
||||
кто сверяет план с исходом. На его вход подаётся этот план — вместо плана
|
||||
разметки, которого нет.
|
||||
|
||||
**Условие третьей строки проверяемое, и смотрится оно по диффу**, а не по
|
||||
намерению: обновление зависимости или правка файла CI кода не трогают, чистка и
|
||||
перенос — трогают. `review-code` — единственный проход, который вообще говорит
|
||||
«здесь ошибка в логике», и чистка, прошедшая без него, проверена только на то,
|
||||
что она собирается.
|
||||
|
||||
**Сигнал о заниженной метке на этом прогоне не работает** — метки нет, и
|
||||
поднимать нечего. Его место занимает признак сценария: показалось, что глубины
|
||||
мало, потому что задача крупнее заявленного, — ищи дельту, а не метку.
|
||||
|
||||
**Границы покрытия называются полностью:**
|
||||
|
||||
- `requirements` — предмета нет, дельта-спек не существует;
|
||||
- `security` — своего прохода нет; сверена против записанных инвариантов внутри
|
||||
`review-code`, а он шёл не всегда. Не шёл — тему не смотрел никто, и это
|
||||
говорится прямо;
|
||||
- `architecture` — то же: только против инвариантов, и только если шёл `code`.
|
||||
|
||||
Отчёт, из которого исчезло «что не смотрел никто», сообщает «проверено», не
|
||||
сообщая, что именно.
|
||||
|
||||
Отработка — как в решении: помеченное `инлайн` чини сам и не логируй, `развилка`
|
||||
— вопросом в запись. После правок снова гейт. Отложенные находки собери в секцию
|
||||
доклада `Урожай`; задачи из него заводит `av-dev:task-track`, не ты.
|
||||
|
||||
### 5. Синк документации — главный шаг этого сценария
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`.** Правило то же и такое же жёсткое:
|
||||
**принуждённое отрицание** — каждый документ канона либо назван обновлённым, либо
|
||||
получает «не требуется, потому что…». Нетронутые группируются одной строкой.
|
||||
|
||||
**Здесь этот шаг весит больше, чем в решении, и вот почему.** Обслуживание не
|
||||
меняет поведения — значит, почти всё, что оно меняет, это документация: команды,
|
||||
шаги гейта, зависимости поимённо, пути, имя основной ветки, настройки с числовым
|
||||
значением, место механизации правила. Ровно эти факты `doc-code-drift` и сверяет
|
||||
с кодом (перечень закрыт, живёт в каноне) — то есть сценарий, чаще всех прочих
|
||||
двигающий сверяемые факты, обязан отчитаться по ним раньше всех прочих.
|
||||
|
||||
Отдельно один документ, которого нет в перечне тем, а синку он нужен:
|
||||
**`conventions.*`, раздел «Механизировано»** — если правило переехало в линтер, и
|
||||
тогда его проза из конвенций **удаляется**, а не остаётся вторым домом.
|
||||
|
||||
**`adr/` этот сценарий не пополняет, и это не пропуск.** У ADR закрытый список
|
||||
источников — архивный `design.md` либо записка разведки, — и ни того ни другого
|
||||
обслуживание не производит. Поэтому триггеры ADR здесь работают **стоп-признаком,
|
||||
а не поводом завести запись**: сработал дорогой откат, намеренный отказ от
|
||||
очевидного подхода или пересмотр прежнего решения — сценарий выбран неверно,
|
||||
объявляй исход **нужна разведка** и останавливайся. Решение с ценой обязано
|
||||
пройти чекпоинт вариантов, а не появиться в коммите обслуживания, чей смысл —
|
||||
«ничего не решали, поменяли оснастку».
|
||||
|
||||
Список документов и их триггеров здесь не дублируется — он в чек-листе скилла
|
||||
`av-dev:doc-sync`; копия уже однажды разошлась с оригиналом. Плагина в проекте
|
||||
нет — иди за перечнем в свой reference,
|
||||
[references/project-facts.md](../../review/references/project-facts.md) конвейера
|
||||
ревью, добавь `adr/` руками и скажи строкой, что синк сделан по перечню
|
||||
документов, без списка триггеров.
|
||||
|
||||
### 6. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**. Вызов не разрешился —
|
||||
напиши сам и скажи строкой, что форму коммита не сверял никто. Одна задача — один
|
||||
осмысленный коммит.
|
||||
|
||||
### 7. Закрыть задачу — после коммита, не раньше
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть задачу как реализованную.
|
||||
Порядок обязателен: закрытие удаляет файл задачи, и сделанное до коммита оно
|
||||
оставило бы задачу закрытой без следа работы, если шаг 6 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же**, сообщением про учёт:
|
||||
`закрыта задача <slug>`. Плагина нет — ничего не выдумывай: скажи, что учёт
|
||||
остаётся за владельцем, и назови исход.
|
||||
|
||||
## Границы: чего обслуживание не делает
|
||||
|
||||
- **Не меняет поведения.** Обнаружилось, что меняет, — стоп с исходом «меняется
|
||||
спека»: назвать тип, объяснить, дать два решения. Это единственная граница
|
||||
сценария, у которой есть проверяемый признак, и она же единственная, которую
|
||||
выгодно нарушить молча.
|
||||
- **Не переписывает запись задачи сам.** Тип ты **предлагаешь** с причиной,
|
||||
меняет его `av-dev:task-track` и только после ответа человека: исполнитель,
|
||||
переклеивший тип на ходу, назначает себе другой процесс и другую глубину
|
||||
проверки.
|
||||
- **Не решает, нужна ли работа.** Как и оба соседних сценария: «надо ли» —
|
||||
вопрос человека.
|
||||
- **Не нарезает пачку на задачи.** «Обновить зависимости и переписать сборку» —
|
||||
это `av-dev:task-track` и его правила нарезки.
|
||||
- **Не выбирает форму правки, когда она незнакома, и не принимает решений с
|
||||
ценой.** Мажорное обновление, смена инструмента, намеренный отказ идут
|
||||
разведкой: там есть чекпоинт вариантов и законный источник для ADR, здесь нет
|
||||
ни того ни другого.
|
||||
- **Не заводит задачи из урожая ревью.** Урожай передаётся списком.
|
||||
|
||||
## Доклад обслуживания
|
||||
|
||||
Общее ядро доклада — в SKILL.md; сверх него сценарий обязан назвать:
|
||||
|
||||
- **что подтвердило признак** — тип записи и то, что дельта-спек не нашлось;
|
||||
дельта нашлась — **какой тип предложен, с причиной, и что человек выбрал**:
|
||||
переформулировать или прекратить;
|
||||
- **что стало иначе для разработчика** — одной фразой, адресуясь ему, а не
|
||||
выдуманному пользователю;
|
||||
- **состав гейта до и после**, если правка его трогала; не сверялся — почему;
|
||||
- по каждому критерию приёмки: **оракул и наблюдаемый исход**;
|
||||
- **`Урожай`** — отложенные находки списком;
|
||||
- **строка границ покрытия**: план сценария фиксирован, разметчик не запускался,
|
||||
`requirements` не смотрел никто, а `security` и `architecture` — только против
|
||||
записанных инвариантов, и то если шёл проход `code`.
|
||||
|
||||
## Тонкости сценария
|
||||
|
||||
- **Самый частый способ соврать этим сценарием — назвать `chore` то, что меняет
|
||||
поведение.** Тип, оставшийся от первой формулировки, врёт ровно там, где по
|
||||
нему выбирают путь; проверка признака стоит одного чтения записи и делается на
|
||||
шаге 1, а не после написанного кода.
|
||||
- **Отсутствие чекпоинта не делает сценарий автономнее прочих.** Правило
|
||||
необратимого здесь то же, и срабатывает оно чаще: выкладка, токены, хуки,
|
||||
чужие данные — обычное содержимое задач обслуживания.
|
||||
- **Зелёный гейт после правки гейта ничего не доказывает.** Это единственное
|
||||
место конвейера, где инструмент проверяет сам себя, и потому состав сверяется
|
||||
отдельно от цвета.
|
||||
- **Правка оснастки, сделанная «заодно» внутри чужой задачи, этим сценарием не
|
||||
проходит вовсе** — она едет в чужом коммите и не получает ни своего ревью, ни
|
||||
своей строки синка. Заметил нужную правку по ходу решения — вопрос в запись,
|
||||
а не правка мимоходом.
|
||||
@@ -0,0 +1,397 @@
|
||||
# Сценарий «разведка»
|
||||
|
||||
Отвечает на вопрос задачи и записывает ответ туда, где он переживёт переписку.
|
||||
Исход — **знание**: уточнённые документы и уточнённые задачи. **Кода этот
|
||||
сценарий не пишет и change не заводит.**
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
ход; общее для обоих сценариев — вход, обращение к соседним плагинам, правило
|
||||
необратимого, доклад — живёт в SKILL.md и тут не пересказывается.
|
||||
|
||||
**Разведка кончается своим исходом, а не переходом к коду.** Выбранный способ
|
||||
реализует сценарий решения, и запускает его **человек**, следующим прогоном по
|
||||
уточнённой записи. Причина не в церемонии: разведка только что переписала
|
||||
постановку, и брать её в работу тем же заходом значит решать за человека, стоит
|
||||
ли делать это сейчас, — а это приоритет, и он не наш.
|
||||
|
||||
## OpenSpec здесь не предпосылка
|
||||
|
||||
**OpenSpec этому сценарию не нужен**, и это единственное место скилла, где он не
|
||||
предпосылка. Разведка не заводит change и не пишет дельта-спеки: её артефакты —
|
||||
документы канона и записи каталога задач. Скилл `opsx:explore` полезен и зовётся,
|
||||
когда плагин в проекте есть; не разрешился — разведка идёт чтением документов,
|
||||
кода и внешних источников, и это говорится строкой доклада, а не отменяет
|
||||
работу.
|
||||
|
||||
## Кого зовёт этот сценарий
|
||||
|
||||
`av-dev:doc-sync` (ответ уезжает в документы канона), `av-dev:task-track`
|
||||
(задачи заводятся и уточняются), `av-dev-git:commit`. Правило обращения к соседям
|
||||
и ветка «вызов не разрешился» — общие, они в [SKILL.md](../SKILL.md).
|
||||
|
||||
**Отсутствие канона бьёт по разведке сильнее, чем по решению**, и сказать об этом
|
||||
строкой мало: без документов у ответа нет дома, и знание осядет в переписке.
|
||||
Назови исход и предложи `av-dev:doc-canon`; работу не останавливай, но адрес
|
||||
ответа тогда выбираешь сам и говоришь об этом вслух.
|
||||
|
||||
## Что этот сценарий требует от входа
|
||||
|
||||
Вход общий у обоих сценариев (SKILL.md, раздел «Вход»); своего здесь три условия.
|
||||
|
||||
**Паспорт читается раньше кода.** Граница домена и «чем проект **не** является»
|
||||
отсекают половину вариантов до того, как их начнут сравнивать, — а сравнение
|
||||
вариантов и есть работа этого сценария.
|
||||
|
||||
**Сырьё — `research` без раздела «Вопрос» — не берётся.** Исход «не доведена» с
|
||||
причиной «запись это сырьё»: у неё нет вопроса, а разведка без вопроса
|
||||
превращается в чтение всего подряд с отчётом «интересно, но неприменимо».
|
||||
Дописывать вопрос за автора не твоя работа — этим занят штурм сырья в
|
||||
`av-dev:task-track`. Назови, чего не хватает, и остановись.
|
||||
|
||||
**Разведка пришла текстом — сформулируй вопрос сам одной фразой и покажи
|
||||
формулировку в первой же реплике.** Разведка, чей вопрос не назван вслух,
|
||||
признаётся удавшейся любым результатом.
|
||||
|
||||
## Ход работы
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["вход: файл, слаг или текст"]
|
||||
s1["1. вопрос и рамки<br/>сырьё без «Вопроса» — отказ"]
|
||||
s2["2. разведка: документы, код,<br/>внешние источники, opsx:explore"]
|
||||
s3(["3. ЧЕКПОИНТ: варианты<br/>2–4 способа, цена каждого,<br/>что становится невозможным"])
|
||||
s4["4. ответ в документы канона<br/>av-dev:doc-sync"]
|
||||
s5["5. задачи: завести и уточнить<br/>av-dev:task-track"]
|
||||
s6["6. вычитка написанного:<br/>документы и записи задач"]
|
||||
s7["7. гейт проекта, затем коммит<br/>av-dev-git:commit"]
|
||||
s8["8. закрыть разведку — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
out["исход назван: знание, задачи,<br/>отказ или «не доведена»"]
|
||||
|
||||
in --> s1 --> s2 --> s3
|
||||
s3 -->|"выбран способ,<br/>отказ или знание"| s4
|
||||
s3 -.->|"вопрос не тот"| s1
|
||||
s4 --> s5 --> s6 --> s7 --> s8 --> out
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при расхождении
|
||||
прав текст.
|
||||
|
||||
## Плановый стоп сценария
|
||||
|
||||
**До чекпоинта умолчание прежнее — делать, а не спрашивать.** Развилка, найденная
|
||||
по ходу разведки, не задаётся отдельным вопросом: она копится в чекпоинт, который
|
||||
рядом и стоит дёшево.
|
||||
|
||||
Стоп здесь один, и стоит он **перед записью**. Причина в цене: пока варианты
|
||||
живут в контексте, смена решения стоит абзаца; записанный в документы и разложенный
|
||||
на задачи выбор стоит правки документов и разбора беклога. Второго стопа — «покажи,
|
||||
что именно уедет в документы» — нет намеренно: всё, что пишет разведка, лежит в
|
||||
git и читается диффом, а второй стоп на каждой разведке вырождается в ритуал
|
||||
одобрения.
|
||||
|
||||
**Правило необратимого действует и здесь** (SKILL.md, «Когда спрашивать вне
|
||||
чекпоинта»), и разведка обманчива: она кажется безобидной, а замер лезет туда, где
|
||||
живут данные — прогон на боевой базе, запрос к внешнему платному источнику. Здесь
|
||||
ошибка не откатывается правкой текста.
|
||||
|
||||
## Границы: чего разведка не делает
|
||||
|
||||
- **Кодом.** Ни строки, включая «маленький черновик, чтобы проверить». Замер,
|
||||
требующий кода, — это отдельная задача, и её нужно назвать, а не написать по
|
||||
ходу. Исключение ровно одно и оно не про изменение системы: одноразовый
|
||||
**читающий** прогон (запрос, замер, скрипт в песочнице), чей результат уезжает
|
||||
в ответ с провенансом и который ничего не оставляет в репозитории.
|
||||
- **Приоритетом.** Заведённая задача встаёт в конец своей секции; где ей стоять
|
||||
в очереди, решает человек на груминге (`av-dev:task-groom`). Разведка, сама
|
||||
ставящая свой исход первым в беклоге, назначает приоритет тому, что только что
|
||||
придумала.
|
||||
- **Форматом задач и документов.** Индексы и документы руками не правятся: их
|
||||
ведут `av-dev:task-track` и `av-dev:doc-sync`. Твоё — содержание ответа, их —
|
||||
форма и дом.
|
||||
- **Определением ценности.** «Нужно ли это делать вообще» — вопрос человека.
|
||||
Разведка отвечает «как это можно сделать и чего каждый способ стоит».
|
||||
- **Решением задачи.** Выбранный способ реализует сценарий решения, и запускает
|
||||
его человек следующим прогоном. Перейти в него по ходу нельзя — это тот самый
|
||||
переход, ради невозможности которого сценарии и разведены.
|
||||
|
||||
## Наблюдаемые исходы сценария
|
||||
|
||||
Четыре, и каждый обязан быть назван в докладе прямо. Первые три — это те самые
|
||||
«заведены задачи, записано знание, отказ», которыми кончается разведка по
|
||||
определению типа `research`:
|
||||
|
||||
- **способ выбран** — ответ записан, задачи заведены или уточнены, они готовы к
|
||||
взятию. Дальше сценарий решения, следующим прогоном, и запускает его человек;
|
||||
- **знание записано** — вопрос закрыт, задач он не породил: ответ ценен сам по
|
||||
себе (замер, устройство внешнего формата, «так работает и менять не нужно»);
|
||||
- **отказ** — проверили, проблемы нет либо подход отвергнут. **Полноправный
|
||||
исход, а не пустая работа**: «не делаем и вот почему» экономит всю работу,
|
||||
которая иначе была бы сделана. Причина записывается — без неё через квартал
|
||||
разведку закажут заново;
|
||||
- **не доведена** — вопроса нет (сырьё), рамки исчерпаны без ответа, или человек
|
||||
на чекпоинте не одобрил ни одного варианта. Названо, что успели узнать и до
|
||||
какой границы.
|
||||
|
||||
## Определение сделанного для разведки
|
||||
|
||||
У сценария решения оно своё (SKILL.md); здесь — короткое и другое. Разведка
|
||||
сделана, когда верно всё:
|
||||
|
||||
1. **ответ записан по адресу, который назвала задача** — раздел «Куда ляжет
|
||||
ответ». Адреса не было, а вопрос был — ты назначил адрес сам и сказал об этом
|
||||
строкой;
|
||||
2. **у каждого числа провенанс** — команда или условия, которыми оно получено.
|
||||
Число без источника проход ревью обязан читать как условие, а не как замер, и
|
||||
разведка, оставившая голые числа, вредна: по ним будут решать;
|
||||
3. **отвергнутые варианты названы с причиной**. Отвергнутое без причины
|
||||
возвращается на следующей разведке как новая идея;
|
||||
4. задачи, которые исход породил, заведены — или явно сказано, что не породил;
|
||||
5. **написанное вычитано** — документы агентом `doc-wording`, записи задач
|
||||
проходами `task-form` и `task-wording`, каждый по своей пачке;
|
||||
6. написанное закоммичено, разведка закрыта.
|
||||
|
||||
## Шаги
|
||||
|
||||
### 1. Вопрос и рамки
|
||||
|
||||
Прочитай запись. У типа `research` два обязательных раздела, и оба нужны тебе
|
||||
прямо сейчас: **«Вопрос»** — на что отвечаем, **«Куда ляжет ответ»** — по какому
|
||||
адресу он ляжет. Адрес назван заранее не из аккуратности: ответ, не имеющий дома,
|
||||
остаётся в переписке, и через квартал разведку заказывают заново.
|
||||
|
||||
**Адрес назначает автор записи, а не ты.** Запись из каталога без него до тебя
|
||||
не доходит: `ready` требует непустыми оба раздела и откажет — это стоп со
|
||||
строкой, чего не хватает, а не повод дописать за автора. Иначе исполнитель сам
|
||||
назначает себе приёмку, а приёмка разведки — это и есть записанный по названному
|
||||
адресу ответ.
|
||||
|
||||
**Адрес назначаешь ты ровно в одном случае** — когда записи нет вовсе: разведка
|
||||
пришла текстом или в проекте нет учёта задач. Тогда скажи об этом строкой, а
|
||||
выбирай по канону, а не по удобству:
|
||||
|
||||
| Что узнали | Дом ответа |
|
||||
| --- | --- |
|
||||
| наблюдение о внешнем мире, замер с провенансом | `docs/research/` |
|
||||
| решение с ценой: намеренный отказ, дорогой откат | `docs/adr/` |
|
||||
| факт об устройстве системы | тема `architecture` (или своя тема проекта) |
|
||||
| граница домена, «чем проект **не** является» | `passport` |
|
||||
| ответ нужен только этой работе | тело самой записи |
|
||||
|
||||
Раздел **«Рамки»**, если он есть, — это граница разведки: сколько копаем, какие
|
||||
источники, что заведомо вне. Рамок нет, а вопрос широкий — **назначь их сам и
|
||||
покажи в первой реплике**. Разведка без рамок утекает: она всегда может узнать
|
||||
ещё немного, и признак «достаточно» изнутри не виден.
|
||||
|
||||
Здесь же проверка на «не тот вопрос»: если из записи видно, что отвечать надо на
|
||||
другое, скажи это сразу, а не после разведки.
|
||||
|
||||
### 2. Разведка
|
||||
|
||||
Порядок чтения — от дешёвого к дорогому, и он не произволен:
|
||||
|
||||
1. **документы канона проекта** — половина вопросов уже отвечена там, и разведка,
|
||||
начатая с кода, переоткрывает написанное;
|
||||
2. **код и его история** — `git log` по узлу отвечает на «почему так» чаще, чем
|
||||
кажется;
|
||||
3. **внешние источники** — документация формата, чужой опыт, спецификации;
|
||||
4. **замер** — если вопрос про числа. Числа снимаются с провенансом, иначе они
|
||||
бесполезны на следующем шаге.
|
||||
|
||||
**Скилл `opsx:explore`** — законный инструмент этого шага, если плагин в проекте
|
||||
есть: он держит форму размышления и не даёт ему растечься. **В explore не пишем
|
||||
код.** Вызов не разрешился — работай чтением, скажи это строкой.
|
||||
|
||||
Развилку разведки **не записывай вопросом** — она и есть предмет следующего шага.
|
||||
|
||||
### 3. Чекпоинт: варианты
|
||||
|
||||
**Остановись и покажи человеку способы решить.** Это плановый стоп сценария и
|
||||
единственное место, где разведка ждёт ответа.
|
||||
|
||||
Форма — короткая, экран текста:
|
||||
|
||||
- **вопрос**, на который отвечаем, одной фразой (он уже есть в записи);
|
||||
- **2–4 варианта**, не больше. Больше четырёх — это не выбор, а список: человек
|
||||
не сравнит, а признает свою неспособность сравнить и попросит рекомендацию.
|
||||
У каждого варианта: в чём суть простыми словами, **что даёт**, **чего стоит**,
|
||||
**что становится невозможным** (это ловится хуже всего и стоит дороже всего);
|
||||
- **рекомендация с причиной**. Человек чаще соглашается, чем выбирает заново;
|
||||
- что известно **недостоверно** и как это проверить, если проверять дёшево;
|
||||
- **что уедет в документы и в задачи**, если возражений нет, — одной строкой.
|
||||
Это не второй стоп, а предупреждение: человек видит объём последствий там же,
|
||||
где принимает решение.
|
||||
|
||||
Что нельзя: приносить варианты, различающиеся только реализацией; прятать
|
||||
отвергнутое (отвергнутый вариант с названной причиной — половина будущего ADR);
|
||||
приносить один вариант и называть это выбором.
|
||||
|
||||
Проверка на простой язык та же, что у чекпоинта решения: **в тексте нет `SHALL`,
|
||||
нет имён файлов и функций там, где вещь называется по-русски, и нет слов, которых
|
||||
нет в паспорте проекта.**
|
||||
|
||||
Исходы чекпоинта:
|
||||
|
||||
- **выбран способ** — идёшь на шаг 4, исход разведки будет «способ выбран». Кода
|
||||
ты по нему не пишешь: сценарий кончается записью и коммитом;
|
||||
- **ответ и есть результат** — идёшь на шаг 4, исход «знание записано» или
|
||||
«отказ»;
|
||||
- **вопрос не тот** — возвращаешься на шаг 1: переформулируй вопрос и скажи, что
|
||||
из разведанного остаётся в силе;
|
||||
- **ни один вариант не одобрен** — исход «не доведена» с причиной. Записывается
|
||||
всё равно то, что узнано (шаг 4): выброшенная разведка будет заказана заново.
|
||||
|
||||
### 4. Ответ в документы канона
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`**: он владеет содержимым документов канона.
|
||||
Передай ему ответ, адрес из шага 1 и провенанс каждого числа — писать содержание
|
||||
за тебя он не будет, но дом и форму держит он. Вычитка языка — тоже его агент, но
|
||||
момент её назван отдельно, шагом 6: пачка собирается из шагов 4 и 5 и до конца
|
||||
пятого не полна.
|
||||
|
||||
**Что именно уезжает:**
|
||||
|
||||
- **ответ на вопрос** — по адресу из шага 1;
|
||||
- **отвергнутые варианты с причинами.** Это половина будущего ADR и единственная
|
||||
защита от повторной разведки того же самого;
|
||||
- **решение с ценой — в ADR**, если оно проходит триггер канона (дорогой откат,
|
||||
намеренный отказ, пересмотр прежнего решения). У разведки, кончившейся без
|
||||
кода, `design.md` не будет никогда, поэтому здесь ADR цитирует **записку
|
||||
разведки**, а не архивный change; канон это допускает прямо, и в записи
|
||||
источник называется.
|
||||
|
||||
**Правило принуждённого отрицания здесь не действует.** Это не синк: разведка
|
||||
трогает те документы, которых коснулся её ответ, и перебирать весь канон ей
|
||||
незачем. Но **названо должно быть каждое место, куда ты писал**, — доклад без
|
||||
перечня адресов неотличим от доклада о ненаписанном.
|
||||
|
||||
**Плагина `av-dev-docs` нет** — путь в его дерево не разрешится ниоткуда, поэтому
|
||||
за перечнем документов иди в **свой** reference:
|
||||
[references/project-facts.md](../../review/references/project-facts.md) конвейера
|
||||
ревью. `docs/adr/` и `docs/research/` в нём отсутствуют намеренно (проход ревью их
|
||||
не открывает), а разведке нужны как раз они — добавь их руками. Пиши сам, скажи
|
||||
строкой: «ответ записан без скилла документации — форму и вычитку не сверял
|
||||
никто».
|
||||
|
||||
### 5. Задачи: завести и уточнить
|
||||
|
||||
**Вызови Skill `av-dev:task-track`.** Он владеет форматом, дедупом и индексами;
|
||||
путь к его скрипту не выясняй и индексы руками не правь.
|
||||
|
||||
Что просишь сделать:
|
||||
|
||||
- **уточнить саму разведку** — если её вопрос по ходу изменился;
|
||||
- **уточнить существующие задачи** — разведка часто отвечает не «что делать», а
|
||||
«что в поставленном неверно»: постановка, границы в разделе «Затрагивает»,
|
||||
критерии приёмки;
|
||||
- **завести новые задачи**, если исход их породил. Формулировки приноси готовыми:
|
||||
заголовок, «зачем», тип, границы. Нарезку на независимо полезные части и
|
||||
проверку на дубли делает он — у него на это свои правила и свой сценарий.
|
||||
|
||||
**Пачку задач показывай списком, прежде чем заводить.** Разведка — самый лёгкий
|
||||
способ надуть беклог: она порождает идеи быстрее, чем кто-либо успевает их
|
||||
оценивать, а заведённая задача живёт, пока её кто-то не выкинет руками.
|
||||
|
||||
Плагина нет — задачи остаются **списком формулировок в докладе**, и это говорится
|
||||
строкой: учёт работ остаётся за владельцем.
|
||||
|
||||
### 6. Вычитка написанного — до гейта, не после
|
||||
|
||||
Разведка правит **две вещи сразу**: документы канона (шаг 4) и записи каталога
|
||||
задач (шаг 5). Обе — текст, и портится он в момент письма, а машина этого не
|
||||
видит: `docs.py check` и `tasks.py check` смотрят форму раскладки, а не залог,
|
||||
оценку без факта, жаргон и термин, которого нет в паспорте проекта.
|
||||
|
||||
Пачка **собирается только сейчас**, и поэтому шаг стоит здесь: раньше пятого шага
|
||||
она не полна, а после коммита вычитка уже правит закоммиченное.
|
||||
|
||||
- **Документы** — агент `doc-wording`, владеет им `av-dev:doc-sync` (раздел
|
||||
«Вычитка»). Пачка — адреса, названные на шаге 4, включая `docs/adr/` и
|
||||
`docs/research/`.
|
||||
- **Записи задач** — два прохода, сперва `task-form`, затем `task-wording`;
|
||||
владеет ими `av-dev:task-track` (раздел «Вычитка: два прохода»). Пачка —
|
||||
заведённые и уточнённые на шаге 5 записи. Заголовок и «зачем» правятся **не
|
||||
молча**: покажи предложенное вместе с тем, что было.
|
||||
|
||||
**Что не правилось, то не вычитывается.** Разведка, кончившаяся одним документом
|
||||
и ни одной задачей, зовёт один проход, и это не пропуск — это названная строкой
|
||||
пачка. Скилл-владелец уже прогнал свою пачку по ходу шага — назови это и второй
|
||||
раз тот же файл не гоняй.
|
||||
|
||||
**Судей канона — `doc-consistency` и `doc-code-drift` — здесь не зови.** Они
|
||||
идут на весь канон разом, стоят дорого, и владеет ими `av-dev:doc-healthcheck`,
|
||||
момент вызова которого выбирает человек. Нужно суждение о согласованности — скажи
|
||||
строкой и предложи `healthcheck`, а не зови агентов сам.
|
||||
|
||||
Ни один проход ничего не правит: они возвращают готовые формулировки,
|
||||
подставляешь их ты — и уже с подставленными идёшь на гейт.
|
||||
|
||||
Плагина нет — вызов не разрешится: скажи строкой, что написанное не вычитывал
|
||||
никто, и обходного пути не выдумывай.
|
||||
|
||||
### 7. Гейт и коммит
|
||||
|
||||
**Сперва гейт проекта** — тот же, что гоняет сценарий решения, и по той же
|
||||
причине: разведка только что правила документы канона и индексы задач, а это
|
||||
ровно то, что машина умеет проверить (`docs.py check`, `tasks.py check --dir`,
|
||||
битые ссылки). Красный гейт чинится здесь, а не оставляется следующему прогону:
|
||||
он придёт за код и получит чужую поломку в наследство.
|
||||
|
||||
Гейта в проекте нет — скажи строкой, что записанное не проверял никто.
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
|
||||
он, и здесь она не пересказывается. Вызов не разрешился — напиши сообщение сам и
|
||||
скажи строкой, что форму коммита не сверял никто.
|
||||
|
||||
Одна разведка — один осмысленный коммит: записанный ответ и заведённые задачи
|
||||
уезжают вместе, потому что порознь они полуправда.
|
||||
|
||||
### 8. Закрыть разведку — после коммита, не раньше
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть запись: ответ записан —
|
||||
`close --implemented`, ушла без ответа — `close --reason`, и строка уезжает в
|
||||
кладбище.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы разведку закрытой без единого следа работы, если шаг 7 упадёт. У
|
||||
разведки это опаснее, чем у решения: следом работы там служит код, а здесь —
|
||||
только записанный ответ. Закрытая разведка без него не оставляет следа вообще —
|
||||
файл задачи удалён, ответ был в переписке.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Сообщение короткое, про
|
||||
учёт, а не про работу: `закрыта задача <slug>`. Правило «одна разведка — один
|
||||
коммит» про работу, а учёт — не работа.
|
||||
|
||||
Плагина в проекте нет — **ничего не выдумывай**: скажи в докладе, что учёт задач
|
||||
остаётся за владельцем, и назови исход.
|
||||
|
||||
## Доклад разведки
|
||||
|
||||
Общая форма доклада — в SKILL.md; у разведки он свой, потому что докладывать
|
||||
нечего из того, о чём спрашивают решение (ни метки ревью, ни критериев приёмки,
|
||||
ни архивного change). Коротко, и в нём обязательно:
|
||||
|
||||
- **исход** одним из четырёх слов;
|
||||
- **вопрос и ответ** — по фразе на каждое. Ответ, который не сворачивается во
|
||||
фразу, — признак того, что разведка отвечала не на один вопрос;
|
||||
- **куда записано** — перечнем адресов, а не «документация обновлена»;
|
||||
- **какие задачи заведены и уточнены** — слагами;
|
||||
- **что вычитано и чем** — пачка документов и пачка записей, каждая со своими
|
||||
проходами; не вычитанное называется прямо, вместе с причиной;
|
||||
- **что осталось неизвестным** и чего это стоит: разведка без этой строки
|
||||
сообщает «выяснено», не сообщая, что именно осталось не выяснено;
|
||||
- **рамки**, если они ограничили работу: докуда копали и почему остановились.
|
||||
|
||||
## Тонкости
|
||||
|
||||
- **Ответ «зависит от» — не ответ.** Если разведка кончилась развилкой, её исход
|
||||
— варианты с ценой, а не пересказ обеих сторон без рекомендации.
|
||||
- **Отрицательный результат записывается так же тщательно, как положительный.**
|
||||
Соблазн не писать его велик: кажется, что писать нечего. Через квартал именно
|
||||
этой записи и не хватит.
|
||||
- **Чужую разведку не переоткрывай молча.** Нашёл в `docs/research/` или в
|
||||
`docs/adr/` ответ на свой вопрос — исход «знание записано» со ссылкой, и это
|
||||
лучшая из возможных разведок: она стоила одного чтения.
|
||||
@@ -0,0 +1,412 @@
|
||||
# Сценарий «решение»
|
||||
|
||||
Способ решения известен, спорно только как. Проводит задачу от постановки до
|
||||
закрытия и **пишет код**: цикл Spec Driven Development с одним плановым стопом —
|
||||
объяснением после ревью дизайна.
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
ход; общее для обоих сценариев — вход, обращение к соседним плагинам, правило
|
||||
записанного вопроса, правило необратимого — живёт в SKILL.md и тут не
|
||||
пересказывается.
|
||||
|
||||
**OpenSpec — жёсткая предпосылка именно этого сценария** (SKILL.md,
|
||||
«Предпосылки»): на нём стоят шаги 2, 6 и 8, проход `review-specs` и ревью
|
||||
дизайна.
|
||||
|
||||
Тонкая обёртка над каноническими скиллами `opsx:propose` / `opsx:apply` /
|
||||
`opsx:archive` — зови их через Skill, не переизобретай их шаги. Ревью — скилл
|
||||
`av-dev:code-review`; он же держит правило выбора метки, а называет её агент
|
||||
`review-scope` — один раз на задачу, для обеих стадий ревью.
|
||||
|
||||
## Ход работы
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["сценарий выбран: решение"]
|
||||
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:doc-sync"]
|
||||
s10["10. коммит работы — av-dev-git:commit"]
|
||||
s11["11. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
|
||||
in --> s1
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10 --> s11
|
||||
s3 -.->|"план задачи: та же метка"| s7
|
||||
s5 -.->|"скорректировать:<br/>меняются дельта-спеки"| s3
|
||||
s7 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||||
расхождении прав текст.
|
||||
|
||||
## Наблюдаемые исходы сценария
|
||||
|
||||
Четыре, и каждый обязан быть назван в докладе прямо:
|
||||
|
||||
- **сделана** — определение сделанного выполнено целиком;
|
||||
- **не доведена** — с причиной и с записанным вопросом; что именно сделано и до
|
||||
какой границы, названо явно. Сюда же попадает чекпоинт, на котором человек
|
||||
решение не одобрил;
|
||||
- **оказалась крупнее задачи** — распознаётся **до заведения change**, иначе его
|
||||
придётся выбрасывать. Дальше — декомпозиция, и это не работа этого скилла;
|
||||
- **нужна разведка** — очевидного способа решения нет, и это выяснилось уже в
|
||||
работе. Стоп с названной причиной; кода не написано ни строки **намеренно**.
|
||||
Разведка идёт следующим прогоном.
|
||||
|
||||
## Определение сделанного
|
||||
|
||||
Задача сделана, когда верно всё:
|
||||
|
||||
1. гейт проекта зелёный;
|
||||
2. ревью проведено, **план прогона сверен с исходом по каждой теме**, темы без
|
||||
отчёта и без дома названы в границах покрытия;
|
||||
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
|
||||
чекпоинт был пройден заново;
|
||||
4. change заархивирован, дельты влиты в актуальные спеки;
|
||||
5. коммит сделан в текущую ветку;
|
||||
6. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
|
||||
оракул и наблюдаемый исход** — «прогнал вот это, увидел вот то». Это **доклад,
|
||||
а не сертификация: приёмка — не работа этого скилла.** Исполнитель, ставящий
|
||||
себе галочку «принято», проверяет свою работу своим же взглядом — по границе
|
||||
это может делать только приёмщик, разведённый с исполнителем. Критерии приходят
|
||||
снаружи; скилл их не сочиняет и не занижает. Расхождение «по каждому критерию
|
||||
исход есть, а суть задачи не достигнута» — дефект критериев, и о нём
|
||||
сообщается, а не молча дорабатывается.
|
||||
|
||||
## Шаги
|
||||
|
||||
### 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` отдельным блоком.
|
||||
Задаче предшествовала разведка — её записка и отвергнутые варианты **уже
|
||||
записаны** в документах канона (`docs/research/`, `docs/adr/`): сошлись на них из
|
||||
`design.md`, а не переписывай второй раз. Варианты, разобранные без разведки
|
||||
(способ был очевиден, но у него оказались оттенки), — в `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`) собери в секцию доклада
|
||||
`Урожай`: формулировка, оракул, провенанс. Задачи из него **заводит не этот
|
||||
скилл** — их заводит `av-dev:task-track` своим сценарием «задачи из ревью и
|
||||
аудита»: своя нарезка, свой формат, свои правила дублей. Твоя обязанность — не
|
||||
потерять и передать.
|
||||
|
||||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
|
||||
### 8. Архивировать — `opsx:archive`
|
||||
|
||||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||||
|
||||
### 9. Синк документации
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`**: он владеет содержимым документов канона и
|
||||
ведёт чек-лист синка.
|
||||
|
||||
**Правило одно и оно жёсткое: принуждённое отрицание.** Доклад обязан назвать
|
||||
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
|
||||
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
|
||||
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
|
||||
работает только обязательное отрицание.
|
||||
|
||||
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
|
||||
`av-dev:doc-sync`, и копия уже однажды разошлась с оригиналом, потеряв два
|
||||
триггера.
|
||||
|
||||
**Плагина `av-dev-docs` в проекте нет** — путь в его дерево не разрешится ниоткуда,
|
||||
поэтому за списком иди в **свой** reference:
|
||||
[references/project-facts.md](../../review/references/project-facts.md)
|
||||
конвейера ревью перечисляет все документы канона с их предметом. Пройди по этому
|
||||
перечню — каждый документ получает строку, отрицание остаётся обязательным.
|
||||
|
||||
**Двух домов в том перечне нет намеренно, а синку они нужны: `docs/adr/` и
|
||||
`docs/research/`.** Проход ревью их не открывает — процессные, — но ADR как раз
|
||||
**главный выход синка**: решение, принятое по ходу задачи, без этой строки
|
||||
теряется систематически. Добавь их к перечню руками: `adr/` — решение с ценой,
|
||||
принятое в этой задаче; `research/` — если по ходу узналось новое о внешнем мире
|
||||
(записку разведки, предшествовавшей задаче, пишет не этот сценарий).
|
||||
Триггеры при этом ты знаешь хуже, и это называется в докладе строкой: «синк
|
||||
сделан по перечню документов, без списка триггеров — плагина `av-dev-docs` нет».
|
||||
Канона в проекте тоже нет — назови это исходом и предложи `av-dev:doc-canon`.
|
||||
|
||||
### 10. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
|
||||
он, и здесь она не пересказывается. Вызов не разрешился — плагина в проекте нет:
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev-tasks`, не ты) — это правки в рабочем
|
||||
дереве, и оставить их незакоммиченными нельзя: закрытие, не доехавшее до основной
|
||||
ветки, оставит задачу открытой молча, а опора «индексы под git показывают, что и
|
||||
когда закрыто» без коммита — пустые слова. Сообщение короткое, про учёт, а не про
|
||||
работу: `закрыта задача <slug>`. Это второй коммит осознанно: правило «одна задача
|
||||
— один осмысленный коммит» про работу, а учёт — не работа.
|
||||
|
||||
Плагина в проекте нет — вызов не разрешится. Тогда **ничего не выдумывай**: скажи
|
||||
в докладе, что учёт задач остаётся за владельцем, и назови исход.
|
||||
|
||||
## Доклад решения
|
||||
|
||||
Общее ядро доклада — в SKILL.md; сверх него сценарий решения обязан назвать:
|
||||
|
||||
- **что было одобрено на чекпоинте и совпало ли с тем, что уехало в коммит** —
|
||||
расхождение здесь называется прямо, даже если оно мелкое;
|
||||
- ссылка на архивный change и хеш коммита;
|
||||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||||
это доклад приёмщику, а не отметка «принято»;
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, провенанс);
|
||||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||||
запускались и что проверить было невозможно. Доклад без неё сообщает
|
||||
«проверено», не сообщая, что именно.
|
||||
|
||||
## Тонкости сценария
|
||||
|
||||
- Гейт блокирует: пока он красный, проходы с мнением не запускаются. Чинить и
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Стиль правок — заточка под проект и конвенции, по размеру задачи, без
|
||||
улучшений заодно.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа.** Отложенные находки
|
||||
отдаются **списком**; превращает их в задачи `av-dev:task-track`, у него на
|
||||
этот вход отдельный сценарий «задачи из ревью и аудита». Плагина нет — урожай
|
||||
остаётся списком в докладе, и это говорится строкой.
|
||||
- **Способ решения ты не выбираешь.** Он приходит известным: из постановки, из
|
||||
разведки, от человека. Выбор между двумя подходами с разной ценой делается в
|
||||
разведке, у своего чекпоинта, — не по ходу этого сценария.
|
||||
Reference in New Issue
Block a user