слияние: три плагина стали одним av-dev, скиллы получили префиксы
Каталоги, агенты и общие дома переехали в av-dev/; скиллы названы по прежнему плагину — doc-*, task-*, code-*, с двумя смысловыми именами вместо тавтологии: doc-sync вместо docs, task-track вместо tasks. Манифесты сведены к двум плагинам. Пространства имён вызовов и пути внутри дерева переписаны машинно; проза, которая называет прежние плагины отдельными, идёт следующим шагом.
This commit is contained in:
@@ -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