resolve: два сценария вместо одной цепочки — разведка и решение
Разведка была прологом к коду: три шага, чекпоинт вариантов — и вливание в общую ветку. Своего исхода у неё не было, поэтому и писать в документы проекта ей было незачем: ответ оседал в design.md будущего change. - у разведки появился исход: ответ уезжает в документы канона, задачи заводятся и уточняются, написанное коммитится, запись закрывается. Кода сценарий не пишет вовсе, OpenSpec ему не нужен - точка входа осталась одна, и сценарий выбирает скилл, прочитав постановку: «есть ли очевидный способ решения» видно после чтения записи, и требовать этого суждения от вызывающего значит требовать его раньше, чем оно возможно - оба сценария лежат справочниками и одинаково — solve.md и research.md, — а в SKILL.md остались вход, развилка и правила, не зависящие от сценария. Асимметрия читалась бы как старшинство: сценарий в теле скилла выглядит основным, а в справочнике — оговоркой - переход между сценариями — событие с названным исходом: решение, упёршееся в незнание способа, останавливается; разведка, выбравшая способ, доводится до конца, а код идёт следующим прогоном, который запускает человек - канон 14: у ADR два законных источника. У решения, принятого разведкой, design.md нет по построению, и такое решение либо не попадало в adr/ вовсе, либо попадало сочинённым заново Правки по своему же ревью, до коммита: - версия 14 была неполной — разрез проверки, вход и устав doc-consistency, скелеты adr/README.md и template.md по-прежнему требовали ссылку на design.md. Агент краснел бы на законной записи; скелеты уезжают в проекты, поэтому запись журнала называет их поимённо - canon.md объявлял себя двенадцатым, пережив версию 13. Литерал был третьим домом числа при двух исправных — убран, а не поправлен - сценарий разведки был недостижим там, где обещал работать: ready требует у research оба раздела, включая «Куда ляжет ответ», а сценарий брался назначить адрес сам. Адрес назначает автор записи; сценарий — только когда записи нет - разведка коммитила без гейта, хотя правит документы канона и индексы задач - при переносе выпало предупреждение про закрытие разведки без записанного ответа — возвращено
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
{
|
||||
"name": "av-dev-code",
|
||||
"source": "./av-dev-code",
|
||||
"description": "Решение одной задачи от постановки до закрытия скиллом resolve — полный цикл Spec Driven Development с двумя плановыми остановками: чекпоинт вариантов у исследовательской задачи и чекпоинт с объяснением человеческим языком после ревью дизайна у всякой. Между ними работа идёт без согласований. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. Требует OpenSpec и сам его заводит скиллом openspec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой."
|
||||
"description": "Одна задача от постановки до закрытия скиллом resolve: точка входа одна, сценария два, и выбирает сценарий сам скилл, прочитав постановку. Сценарий решения — полный цикл Spec Driven Development с плановым чекпоинтом после ревью дизайна: объяснение человеческим языком, повод скорректировать ход решения. Сценарий разведки (тип research, сырая идея, мутная постановка) кода не пишет и change не заводит: его чекпоинт вариантов стоит до первого написанного требования, а исход уезжает в документы канона и в задачи; выбранный способ реализуется следующим прогоном, который запускает человек. Смена сценария по ходу — событие с названным исходом, а не тихий поворот. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. OpenSpec нужен сценарию решения, и плагин сам его заводит скиллом openspec; разведка обходится без него. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой."
|
||||
},
|
||||
{
|
||||
"name": "av-dev-git",
|
||||
|
||||
@@ -3713,3 +3713,69 @@ change нет — берём источником актуальные спек
|
||||
на вопрос «по какой записи повышать», а не «сделаны ли шаги по существу».
|
||||
Машина, приписывающая недостающее число сама, объявляет проект приведённым
|
||||
к формату, которого никто не проходил.
|
||||
|
||||
## 61. Разведка и решение — два сценария одного скилла, а не два скилла (2026-08-11)
|
||||
|
||||
Скилл `resolve` вёл обе работы одной цепочкой: у исследовательской задачи были
|
||||
свои три шага и свой чекпоинт вариантов, после которого она **вливалась в общую
|
||||
ветку** и продолжалась кодом. Разведка тем самым была не работой со своим
|
||||
исходом, а прологом к коду: её ответ оседал в `design.md` будущего change, и
|
||||
разведка, кончившаяся знанием, документов проекта не касалась вовсе.
|
||||
|
||||
Сперва я развёл их на два скилла — `resolve` и `research`, с исходом и стопом с
|
||||
обеих сторон. Через час работы стало видно, чем это плохо: **классифицировать
|
||||
задачу приходится человеку до вызова**, а «есть ли у неё очевидный способ
|
||||
решения» видно только после чтения записи. Разделение переносило самое трудное
|
||||
суждение туда, где для него меньше всего данных.
|
||||
|
||||
**Решено: точка входа одна, сценария два, выбирает сценарий скилл.** Оба сценария
|
||||
живут справочниками — `references/solve.md` и `references/research.md`, — а в
|
||||
`SKILL.md` остались вход, развилка и правила, не зависящие от сценария. Тем же
|
||||
приёмом сложен скилл задач: общая часть в `SKILL.md`, алгоритм каждого типа в
|
||||
`references/task-*.md`.
|
||||
|
||||
**Порознь и одинаково — это отдельное решение.** Сперва разведка уехала в
|
||||
справочник, а решение осталось в теле скилла: так вышло само, потому что решение
|
||||
там уже лежало. Асимметрия читается как старшинство — сценарий в теле выглядит
|
||||
основным, а сценарий в справочнике оговоркой, — и удерживает шестисотстрочный
|
||||
файл, который грузится целиком даже ради разведки.
|
||||
|
||||
**Что у разведки появилось своего.** Исход — знание, а не пролог: ответ уезжает в
|
||||
документы канона (`av-dev-docs:docs`), задачи заводятся и уточняются
|
||||
(`av-dev-tasks:tasks`), написанное коммитится, запись закрывается. Кода сценарий
|
||||
не пишет вовсе. OpenSpec ему не нужен — это единственное место скилла, где тот не
|
||||
предпосылка.
|
||||
|
||||
**Переход между сценариями — событие с названным исходом.** Решение, упёршееся в
|
||||
незнание способа, останавливается; разведка, выбравшая способ, доводится до конца
|
||||
и **не переходит в код тем же прогоном** — следующий запускает человек. Причина
|
||||
не в церемонии: разведка только что переписала постановку, и брать её в работу
|
||||
тем же заходом значит решать за человека, стоит ли делать это сейчас, — а это
|
||||
приоритет.
|
||||
|
||||
**Канон пришлось тронуть, и это версия 14.** ADR цитировал только архивный
|
||||
`design.md`. У решения, принятого разведкой, `design.md` нет по построению —
|
||||
change по нему не будет никогда, — и такое решение либо не попадало в `adr/`
|
||||
вовсе, либо попадало сочинённым заново. Теперь источников два, и оба называются в
|
||||
записи.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
204. **Разделять работы стоит по моменту для человека, а не по роду работы.**
|
||||
У разведки и решения он разный: варианты обсуждают до первого требования,
|
||||
объяснение — после ревью дизайна. Всё остальное различие (пишем код или нет)
|
||||
из этого уже следует.
|
||||
205. **Точку входа не разделяют по признаку, который виден только внутри.**
|
||||
Классификация, требующая прочитать запись, не может быть условием вызова:
|
||||
человек либо ошибётся, либо прочитает запись сам — и тогда скилл ему не
|
||||
нужен.
|
||||
206. **Сценарий в справочнике дешевле скилла.** Скилл стоит описания, границ,
|
||||
копии правил и своего места в графе вызовов; справочник наследует их у
|
||||
хозяина. Заводить второй скилл имеет смысл, когда его зовут отдельно, а не
|
||||
когда он просто длинный.
|
||||
207. **Равные сценарии лежат одинаково.** Оставить один в теле скилла, а второй
|
||||
вынести — значит назначить первому старшинство, которого в замысле нет.
|
||||
Читатель это старшинство считывает, даже когда о нём не сказано ни слова.
|
||||
208. **Работа без своего исхода вырождается в пролог.** Разведка, кончавшаяся
|
||||
переходом к коду, не имела причины писать в документы: её ответ и так уезжал
|
||||
в `design.md`. Дом для исхода — вот что делает работу работой.
|
||||
|
||||
@@ -36,19 +36,28 @@
|
||||
очереди, и живёт он в индексе. Интерактивный: разбирает вопросы пачкой,
|
||||
переоценивает порциями по 5–8, расставляет верх очереди с доводом на
|
||||
каждое движение.
|
||||
- **av-dev-code** — код по задачам: решение одной задачи и его проверка.
|
||||
Владеет `openspec/`. **Требует OpenSpec и сам его заводит.**
|
||||
- **av-dev-code** — работа по задачам: разведка, решение и проверка сделанного.
|
||||
Владеет `openspec/`. **Требует OpenSpec и сам его заводит** — кроме сценария
|
||||
разведки, которому он не нужен.
|
||||
- `openspec` — завести, настроить и **проверить** `openspec/` в проекте:
|
||||
`openspec init`, замена примера в `config.yaml` настройкой канонической
|
||||
формы, скрипт `openspec.py` (форма файла + сверка слепка с живой версией
|
||||
инструмента). Каталог принадлежит конвейеру, а не канону: без конвейера он
|
||||
проекту не нужен, и `docs.py` о нём молчит;
|
||||
- `resolve` — одна задача от постановки до закрытия. Обычная идёт циклом SDD
|
||||
с **чекпоинтом после ревью дизайна**: объяснение человеческим языком, повод
|
||||
скорректировать ход решения. Исследовательская начинается с `opsx:explore` и
|
||||
**чекпоинта вариантов** — способы решить, цена каждого, рекомендация; выбор
|
||||
оседает по адресу, который назвала сама задача. Между чекпоинтами — без
|
||||
согласований;
|
||||
- `resolve` — одна задача от постановки до закрытия. **Точка входа одна, а
|
||||
сценария два, и выбирает сценарий сам скилл, прочитав постановку:**
|
||||
классифицировать задачу до вызова человек всё равно не может — «есть ли
|
||||
очевидный способ решения» видно после чтения записи.
|
||||
**Решение** идёт циклом SDD с чекпоинтом после ревью дизайна: объяснение
|
||||
человеческим языком, повод скорректировать ход.
|
||||
**Разведка** (тип `research`, сырая идея, мутная постановка) кода не пишет
|
||||
вовсе: её чекпоинт — варианты, 2–4 способа решить с ценой каждого, — стоит до
|
||||
первого написанного требования, а исход уезжает в документы канона и в
|
||||
задачи. Выбранный способ реализуется **следующим прогоном**, и запускает его
|
||||
человек: смена сценария по ходу — событие с названным исходом, а не тихий
|
||||
поворот. Оба сценария лежат справочниками и одинаково — `references/solve.md`
|
||||
и `references/research.md`; в самом скилле только вход, развилка и правила,
|
||||
не зависящие от сценария. OpenSpec нужен решению, разведке — нет;
|
||||
- `review` — конвейер ревью **по темам**: документ проекта либо
|
||||
заводит тему проверки, либо питает чужую тему источником, либо процессный и в
|
||||
ревью не читается вовсе. Разметка идёт **один раз на задачу**, сразу после
|
||||
@@ -69,9 +78,9 @@
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph pipe["av-dev-code — исполнение, требует OpenSpec"]
|
||||
subgraph pipe["av-dev-code — исполнение; сценарий решения требует OpenSpec"]
|
||||
direction LR
|
||||
tp["resolve<br/>2 чекпоинта человеку"] --> rp["review<br/>10 агентов-проходов"]
|
||||
tp["resolve<br/>2 сценария: разведка и решение"] --> rp["review<br/>10 агентов-проходов"]
|
||||
osp["openspec<br/>заводит и проверяет openspec/"]
|
||||
end
|
||||
subgraph docsp["av-dev-docs — документация, владеет docs/"]
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
цикл SDD, конвейер ревью, OpenSpec), `av-dev-git`. Общее, что нужно нескольким
|
||||
дословно, живёт домом в `shared/` и уезжает копиями.
|
||||
|
||||
Канон документов — **версия 13**; формат задач — **версия 1**, своя и со своим журналом. Живые проекты стоят на 2–3 и на плагине
|
||||
Канон документов — **версия 14**; формат задач — **версия 1**, своя и со своим журналом. Живые проекты стоят на 2–3 и на плагине
|
||||
`av-dev-pm`, которого больше нет.
|
||||
|
||||
Бумажная часть закрыта аудитом четырёх плагинов и четырьмя пропусками правок
|
||||
@@ -42,7 +42,7 @@
|
||||
- [ ] удалить проектные копии: `.claude/skills/healthlog-{task,review}-pipeline`
|
||||
и девять `.claude/agents/healthlog-review-*.md`. Они прошлого поколения и
|
||||
после переезда указывают на документы, которых уже не будет
|
||||
- [ ] `av-dev-docs:canon` в режиме `adopt` — он приведёт проект к канону 13
|
||||
- [ ] `av-dev-docs:canon` в режиме `adopt` — он приведёт проект к канону 14
|
||||
сразу, картой и с подтверждением. Файл-в-файл здесь не расписан: раскладку
|
||||
знает скилл, и второй перечень разошёлся бы с ним
|
||||
- [ ] каталог задач — в `tasks/` корня (канон 11), не в `docs/tasks/`, без
|
||||
@@ -84,9 +84,14 @@
|
||||
|
||||
## 4. Конвейер: что осталось после `resolve`
|
||||
|
||||
Сам скилл написан (`av-dev-code:resolve`, два чекпоинта, ветка разведки),
|
||||
`task-batch` удалён. Осталось то, что на бумаге не проверяется:
|
||||
Сам скилл написан (`av-dev-code:resolve`, два сценария — разведка и решение,
|
||||
по чекпоинту у каждого), `task-batch` удалён. Осталось то, что на бумаге не
|
||||
проверяется:
|
||||
|
||||
- [ ] прогнать сценарий разведки на живой задаче: он написан целиком на бумаге и
|
||||
не исполнялся ни разу. Самое неизвестное — выбор сценария на входе (не
|
||||
уедет ли всё в решение, потому что «способ вроде понятен») и объём того,
|
||||
что разведка пишет в документы
|
||||
- [ ] перемерить скилл `review` тем же вопросом, что и проект целиком:
|
||||
сколько из его стадий реально смотрятся глазами. Тысяча строк, и весь
|
||||
автоматический участок между чекпоинтами держится на них
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "av-dev-code",
|
||||
"description": "Решение одной задачи от постановки до закрытия скиллом resolve — полный цикл Spec Driven Development с двумя плановыми остановками: чекпоинт вариантов у исследовательской задачи и чекпоинт с объяснением человеческим языком после ревью дизайна у всякой. Между ними работа идёт без согласований. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. Требует OpenSpec и сам его заводит скиллом openspec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой.",
|
||||
"description": "Одна задача от постановки до закрытия скиллом resolve: точка входа одна, сценария два, и выбирает сценарий сам скилл, прочитав постановку. Сценарий решения — полный цикл Spec Driven Development с плановым чекпоинтом после ревью дизайна: объяснение человеческим языком, повод скорректировать ход решения. Сценарий разведки (тип research, сырая идея, мутная постановка) кода не пишет и change не заводит: его чекпоинт вариантов стоит до первого написанного требования, а исход уезжает в документы канона и в задачи; выбранный способ реализуется следующим прогоном, который запускает человек. Смена сценария по ходу — событие с названным исходом, а не тихий поворот. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. OpenSpec нужен сценарию решения, и плагин сам его заводит скиллом openspec; разведка обходится без него. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой.",
|
||||
"author": {
|
||||
"name": "Anton Vakhrushev",
|
||||
"email": "anwinged@gmail.com"
|
||||
|
||||
+125
-491
@@ -1,29 +1,42 @@
|
||||
---
|
||||
name: resolve
|
||||
description: "Решить одну задачу от постановки до закрытия. На входе путь к файлу задачи, её слаг или просто текст. Обычная задача идёт циклом Spec Driven Development: opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие. Исследовательская (тип research, сырая идея, мутная постановка) начинается раньше: opsx explore и чекпоинт вариантов — два-четыре способа решить, с ценой каждого и рекомендацией; выбор оседает по адресу, который назвала сама задача. Между чекпоинтами работа идёт без согласований. Использовать, когда просят взять, сделать или решить задачу, довести идею до реализации, разобраться с записью из беклога."
|
||||
description: "Взять одну задачу и довести её до закрытия. Одна точка входа, два сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ решения известен — сценарий решения: цикл Spec Driven Development (opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие). Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст. Использовать, когда просят взять, сделать или решить задачу, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога."
|
||||
---
|
||||
|
||||
# Решение одной задачи
|
||||
# Работа над одной задачей
|
||||
|
||||
Проводит **одну** задачу от постановки до закрытия. Между плановыми
|
||||
остановками — без согласований: механику не обсуждаем, делаем.
|
||||
Проводит **одну** задачу от постановки до закрытия. Вокруг планового стопа — без
|
||||
согласований: механику не обсуждаем, делаем.
|
||||
|
||||
Тонкая обёртка над каноническими скиллами `opsx:explore` / `opsx:propose` /
|
||||
`opsx:apply` / `opsx:archive` — зови их через Skill, не переизобретай их шаги.
|
||||
Ревью — скилл `av-dev-code:review`; он же держит правило выбора
|
||||
метки, а называет её агент `review-scope` — один раз на задачу, для обеих стадий
|
||||
ревью.
|
||||
**Сценария два, а точка входа одна.** Какой из них идёт, решает **скилл**,
|
||||
прочитав постановку, а не человек до вызова: «есть ли у задачи очевидный способ
|
||||
решения» видно после чтения записи, и требовать этого суждения от вызывающего
|
||||
значит требовать его раньше, чем оно возможно.
|
||||
|
||||
| Сценарий | Когда | Чем кончается |
|
||||
| --- | --- | --- |
|
||||
| **решение** | способ известен, спорно только как | код, ревью, архив, коммит, закрытие |
|
||||
| **разведка** | способа нет: тип `research`, сырая идея, мутная постановка | ответ в документах, задачи, коммит, закрытие |
|
||||
|
||||
Ход каждого сценария живёт своим справочником: **решение** —
|
||||
[references/solve.md](references/solve.md), **разведка** —
|
||||
[references/research.md](references/research.md). Здесь только общее: вход,
|
||||
развилка, правила, которые не зависят от сценария. Сценарии лежат порознь и
|
||||
одинаково, потому что привилегированного среди них нет: тот, что жил бы прямо
|
||||
здесь, читался бы как основной, а второй — как оговорка.
|
||||
|
||||
## Предпосылки
|
||||
|
||||
- **OpenSpec и скиллы `opsx:*` — жёсткая предпосылка, а не опция.** На них стоят
|
||||
шаги 2, 6 и 8, шаг Р2 разведки, проход `review-specs` и ревью дизайна (они
|
||||
завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||
- **OpenSpec и скиллы `opsx:*` — жёсткая предпосылка сценария решения**, а не
|
||||
опция. На них стоят его шаги 2, 6 и 8, проход `review-specs` и ревью дизайна
|
||||
(они завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
||||
подключай OpenSpec, а не вырождай цикл; почему ветка деградации здесь не
|
||||
подключай OpenSpec, а не вырождай цикл сценария; почему ветка деградации здесь
|
||||
не
|
||||
пишется, сказано в `av-dev-code:review`, раздел «Предпосылки», и дом у этого
|
||||
довода там. Заводить руками не надо: каталог и настройку в `config.yaml`
|
||||
делает скилл `av-dev-code:openspec`.
|
||||
делает скилл `av-dev-code:openspec`. **Сценарию разведки OpenSpec не нужен** —
|
||||
она не заводит change; `opsx:explore` берётся, если плагин есть.
|
||||
- **Проектные копии этих скиллов и агентов удаляются при установке плагина**
|
||||
(`.claude/skills/` — голые имена `resolve`, `review`, а у проектов прошлого
|
||||
поколения ещё `task-pipeline`, `review-pipeline`, `task-batch`, и с префиксом
|
||||
@@ -91,74 +104,87 @@ description: "Решить одну задачу от постановки до
|
||||
когда сверять уже не с чем.
|
||||
|
||||
**`ready` отказал — это исход, а не препятствие для тебя.** Скажи, чего не
|
||||
хватает, и остановись: дописывать чужую запись за автора не твоя работа, а у
|
||||
сырья (`research` без раздела «Вопрос») и дописывать нечего — там сперва нужен
|
||||
вопрос. Исход — «не доведена», с названной причиной.
|
||||
хватает, и остановись: дописывать чужую запись за автора не твоя работа. Исход —
|
||||
«не доведена», с названной причиной.
|
||||
|
||||
**Отказ `ready` сценарий не выбирает.** Запись `research` без раздела «Вопрос»
|
||||
(сырьё) — отказ и здесь: у неё нет вопроса, и разведывать нечего.
|
||||
|
||||
Плагина `av-dev-tasks` в проекте нет или задача пришла текстом — прогонять
|
||||
нечего. Тогда прочитай постановку сам и скажи строкой, что готовность машиной не
|
||||
проверялась; работу при этом не останавливай.
|
||||
|
||||
## Две ветки
|
||||
## Развилка: какой сценарий
|
||||
|
||||
Развилка одна и стоит на входе:
|
||||
Она одна, и стоит до всякой работы: **есть ли у задачи один очевидный способ
|
||||
решения?**
|
||||
|
||||
- **обычная задача** — что делать, понятно; спорно только как. Идёт с шага 1;
|
||||
- **исследовательская** — тип `research`, сырая идея, новое и незнакомое, мутная
|
||||
постановка. Идёт с шага Р1, и там её ждёт **свой** чекпоинт: варианты решения
|
||||
обсуждаются **до** того, как написано первое требование.
|
||||
- **есть** — что делать, понятно; спорно только как. **Сценарий решения** —
|
||||
[references/solve.md](references/solve.md);
|
||||
- **нет** — тип `research`, сырая идея, новое и незнакомое, мутная постановка,
|
||||
два подхода с разной ценой. **Сценарий разведки** —
|
||||
[references/research.md](references/research.md).
|
||||
|
||||
Признак не в объёме работы, а в том, **есть ли у задачи один очевидный способ
|
||||
решения**. Его нет — обсуждать варианты после `propose` поздно: предложение уже
|
||||
воплотило один из них, и разговор пойдёт не о выборе, а о переделке.
|
||||
Признак не в объёме работы. Крупная задача с очевидным способом идёт в решение;
|
||||
маленькая, но незнакомая — в разведку. Тип `research` в разведку идёт всегда: её
|
||||
исход знание, а не изменение системы.
|
||||
|
||||
**Назови выбранный сценарий вслух первой репликой** — одной строкой, с причиной.
|
||||
Молча выбранный сценарий человек обнаруживает по тому, что работа пошла не туда,
|
||||
и обнаруживает поздно.
|
||||
|
||||
### Сценарий выбирается один раз
|
||||
|
||||
**Смена сценария по ходу — событие, а не тихий поворот**, и каждая из двух смен
|
||||
устроена по-своему:
|
||||
|
||||
- **решение → разведка**: обнаружилось, что очевидного способа нет. Это **стоп**
|
||||
с исходом «нужна разведка»: назови, что именно неясно, и не продолжай.
|
||||
Кода к этому моменту не написано, и писать его «пока разбираемся» нельзя;
|
||||
- **разведка → решение**: способ выбран на чекпоинте вариантов. Разведка **всё
|
||||
равно доводится до конца** — ответ записан, задачи уточнены, коммит сделан, —
|
||||
и решение идёт **следующим прогоном**, который запускает человек.
|
||||
|
||||
**Соблазн «разведаю по ходу» живёт именно здесь**, и он дорог тем, что выглядит
|
||||
экономией одного прогона. Разведка внутри решения не имеет своего чекпоинта:
|
||||
выбор делается тем, кто уже начал писать, и человек видит его только в
|
||||
объяснении, где обсуждать выбор поздно. Ровно за это сценарии и разведены — не за
|
||||
то, что это разные работы, а за то, что у них разные моменты для человека.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["вход: файл, слаг или текст"]
|
||||
ready["ready: готовность записи<br/>av-dev-tasks:tasks"]
|
||||
fork{"есть очевидный<br/>способ решения?"}
|
||||
r1["Р1. понять вопрос<br/>сырьё без «Вопроса» — отказ"]
|
||||
r2["Р2. opsx:explore — груминг"]
|
||||
r3(["Р3. ЧЕКПОИНТ: варианты<br/>2–4 способа, цена каждого,<br/>рекомендация"])
|
||||
rout["исход без кода:<br/>ответ записан / отказ / родились задачи"]
|
||||
s1["1. прочитать задачу<br/>критерии приёмки выписать сразу"]
|
||||
s2["2. opsx:propose — change, дельта-спеки, tasks.md"]
|
||||
s3["3. разметка — review-scope:<br/>размер, сложность, метка, план тем"]
|
||||
s4["4. ревью дизайна, состав по метке<br/>+ отработка замечаний"]
|
||||
s5(["5. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
|
||||
s6["6. opsx:apply — код, гейт,<br/>поведенческая верификация"]
|
||||
s7["7. ревью кода, та же метка<br/>+ отработка замечаний"]
|
||||
s8["8. opsx:archive"]
|
||||
s9["9. синк документации — av-dev-docs:docs"]
|
||||
s10["10. коммит работы — av-dev-git:commit"]
|
||||
s11["11. закрыть задачу — av-dev-tasks:tasks,<br/>вторым коммитом учёта"]
|
||||
solve["сценарий решения<br/>references/solve.md<br/>код, ревью, архив, коммит"]
|
||||
res["сценарий разведки<br/>references/research.md<br/>ответ в документы и задачи"]
|
||||
|
||||
in --> fork
|
||||
fork -->|"да"| s1
|
||||
fork -->|"нет"| r1
|
||||
r1 --> r2 --> r3
|
||||
r3 -->|"выбран способ"| s1
|
||||
r3 -.->|"кода не будет"| rout
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10 --> s11
|
||||
s3 -.->|"план задачи: та же метка"| s7
|
||||
s5 -.->|"скорректировать:<br/>меняются дельта-спеки"| s3
|
||||
s7 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
in --> ready --> fork
|
||||
fork -->|"да"| solve
|
||||
fork -->|"нет"| res
|
||||
solve -.->|"способа всё же нет:<br/>стоп, кода не написано"| res
|
||||
res -.->|"способ выбран:<br/>следующим прогоном,<br/>зовёт человек"| solve
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||||
расхождении прав текст.
|
||||
Схема — **сводка**: содержание сценариев в их справочниках, и при расхождении
|
||||
прав справочник.
|
||||
|
||||
## Автономность и два плановых стопа
|
||||
## Автономность и плановый стоп
|
||||
|
||||
**Между чекпоинтами умолчание прежнее — делать, а не спрашивать.** Чекпоинты не
|
||||
отменяют автономность, они дают развилкам плановое место, куда копиться.
|
||||
**У каждого сценария ровно один плановый стоп**, и стоят они в разных местах:
|
||||
у решения — объяснение после ревью дизайна, у разведки — варианты до первого
|
||||
написанного требования. Правило вокруг них общее.
|
||||
|
||||
**Вокруг чекпоинта умолчание прежнее — делать, а не спрашивать.** Чекпоинт не
|
||||
отменяет автономность, он даёт развилкам плановое место, куда копиться.
|
||||
|
||||
Разрез простой:
|
||||
|
||||
- развилка найдена **до** ближайшего чекпоинта — она его и ждёт. Не спрашивай
|
||||
отдельно: чекпоинт рядом и стоит дёшево, а три вопроса подряд стоят дороже
|
||||
одного разговора;
|
||||
- развилка найдена **после** последнего чекпоинта — старое правило: **запиши
|
||||
вопрос и доведи остаток**, не останавливаясь.
|
||||
- развилка найдена **до** чекпоинта — она его и ждёт. Не спрашивай отдельно:
|
||||
чекпоинт рядом и стоит дёшево, а три вопроса подряд стоят дороже одного
|
||||
разговора;
|
||||
- развилка найдена **после** чекпоинта — старое правило: **запиши вопрос и доведи
|
||||
остаток**, не останавливаясь.
|
||||
|
||||
Запись вопроса устроена так:
|
||||
|
||||
@@ -171,7 +197,8 @@ flowchart TD
|
||||
2. **Переформулируй задачу на остаток** — то, что делается без этого решения.
|
||||
Назови границу: докуда доводим сейчас.
|
||||
3. Доведи остаток до конца и закоммить. Задача не «висит на вопросе», она сделана
|
||||
в объявленных границах.
|
||||
в объявленных границах. В разведке остаток — это ответ в объявленных рамках:
|
||||
что успели узнать, где остановились и почему.
|
||||
|
||||
**Что остатком не является — правило живёт не здесь.** Канонический текст с обеими
|
||||
оговорками — в плагине `av-dev-tasks`, скилл `av-dev-tasks:groom`, раздел
|
||||
@@ -194,7 +221,7 @@ flowchart TD
|
||||
Нет полезного остатка — задача заканчивается исходом «не доведена», вопрос
|
||||
записан, ничего не коммитится наполовину.
|
||||
|
||||
### Когда спрашивать вне чекпоинтов
|
||||
### Когда спрашивать вне чекпоинта
|
||||
|
||||
По другому основанию — не «сложное решение», а **необратимое действие**:
|
||||
|
||||
@@ -205,453 +232,60 @@ flowchart TD
|
||||
Здесь ошибка не откатывается коммитом, поэтому спрашиваем даже когда решение
|
||||
кажется очевидным.
|
||||
|
||||
Стиль правок — заточка под проект и конвенции, right-size, без золочения.
|
||||
|
||||
## Границы: чем этот скилл не владеет
|
||||
|
||||
- **Беклогом, целями и приоритетами.** Задача приходит извне. Скилл её не
|
||||
выбирает, не приоритизирует, не заводит и не переоценивает.
|
||||
- **Форматом задач.** Индексы руками не правятся, путь к скрипту учёта не
|
||||
выдумывается: этим владеет `av-dev-tasks:tasks` (шаг 11). Закрытие — работа
|
||||
этого скилла, и это осознанное решение с названной ценой: **приёмщик и
|
||||
исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на
|
||||
- **Форматом задач и документов.** Индексы и документы канона руками не правятся,
|
||||
путь к чужому скрипту не выдумывается: этим владеют `av-dev-tasks:tasks` и
|
||||
`av-dev-docs:docs`. Закрытие — работа этого скилла, и это осознанное решение с
|
||||
названной ценой: **приёмщик и исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на
|
||||
груминге (`av-dev-tasks:groom`) возвращает задачу `reopen` с причиной, а доклад
|
||||
по критериям приёмки становится единственным, по чему приёмка вообще возможна.
|
||||
- **Заведением задач из урожая ревью.** Отложенные находки отдаются **списком**;
|
||||
превращать их в задачи — работа `av-dev-tasks:tasks`, у него на этот вход
|
||||
отдельный сценарий «задачи из ревью и аудита». Плагина нет — урожай остаётся
|
||||
списком в докладе, и это говорится строкой.
|
||||
- **Определением ценности.** «Нужна ли эта функциональность» — не вопрос этого
|
||||
скилла ни на одном шаге. Чекпоинт спрашивает «так ли решаем», а не «надо ли».
|
||||
скилла ни на одном шаге и ни в одном сценарии. Чекпоинт решения спрашивает «так
|
||||
ли решаем», чекпоинт разведки — «каким из способов», но не «надо ли».
|
||||
|
||||
Что не принадлежит **отдельному сценарию**, названо у него же: урожай ревью и
|
||||
выбор способа — в [solve.md](references/solve.md), код и приоритет — в
|
||||
[research.md](references/research.md).
|
||||
|
||||
## Наблюдаемые исходы
|
||||
|
||||
Ровно четыре, и каждый обязан быть назван в докладе прямо:
|
||||
|
||||
- **сделана** — определение сделанного выполнено целиком;
|
||||
- **не доведена** — с причиной и с записанным вопросом; что именно сделано и до
|
||||
какой границы, названо явно. Сюда же попадает чекпоинт, на котором человек
|
||||
решение не одобрил;
|
||||
- **оказалась крупнее задачи** — распознаётся **до заведения change**, иначе его
|
||||
придётся выбрасывать. Дальше — декомпозиция, и это не работа этого скилла;
|
||||
- **знание вместо изменения** — только у исследовательской ветки: ответ записан
|
||||
по названному адресу, кода задача не потребовала. Это полноправный исход, а не
|
||||
недоведённая работа.
|
||||
|
||||
## Определение сделанного
|
||||
|
||||
Задача сделана, когда верно всё:
|
||||
|
||||
1. гейт проекта зелёный;
|
||||
2. ревью проведено, **план прогона сверен с исходом по каждой теме**, темы без
|
||||
отчёта и без дома названы в границах покрытия;
|
||||
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
|
||||
чекпоинт был пройден заново;
|
||||
4. change заархивирован, дельты влиты в актуальные спеки;
|
||||
5. коммит сделан в текущую ветку;
|
||||
6. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
|
||||
оракул и наблюдаемый исход** — «прогнал вот это, увидел вот то». Это **доклад,
|
||||
а не сертификация: приёмка — не работа этого скилла.** Исполнитель, ставящий
|
||||
себе галочку «принято», проверяет свою работу своим же взглядом — по границе
|
||||
это может делать только приёмщик, разведённый с исполнителем. Критерии приходят
|
||||
снаружи; скилл их не сочиняет и не занижает. Расхождение «по каждому критерию
|
||||
исход есть, а суть задачи не достигнута» — дефект критериев, и о нём
|
||||
сообщается, а не молча дорабатывается.
|
||||
|
||||
У разведки, кончившейся знанием, определение своё и короткое: **ответ записан по
|
||||
адресу, который назвала задача**, и в нём есть провенанс у каждого числа.
|
||||
|
||||
## Исследовательская ветка
|
||||
|
||||
### Р1. Понять вопрос
|
||||
|
||||
Прочитай запись. У типа `research` в ней два обязательных раздела, и оба нужны
|
||||
тебе прямо сейчас: **«Вопрос»** — на что отвечаем, **«Куда ляжет ответ»** — по
|
||||
какому адресу он ляжет. Адрес назван заранее не из аккуратности: ответ, не
|
||||
имеющий дома, остаётся в переписке, и через квартал разведку заказывают заново.
|
||||
|
||||
Вопроса нет — исход «не доведена» с причиной «запись это сырьё»: назови, что
|
||||
нужно дописать, и остановись. Адреса нет, а вопрос есть — назначь адрес сам и
|
||||
скажи об этом строкой: разведка без дома для ответа хуже несделанной.
|
||||
|
||||
Задача не из каталога (пришла текстом) — адреса у неё нет по построению. Тогда
|
||||
дом ответа — `design.md` того change, который родится дальше; кода не будет —
|
||||
`docs/research/`, и это тоже говорится строкой.
|
||||
|
||||
### Р2. Груминг — `opsx:explore`
|
||||
|
||||
Вызови Skill `opsx:explore`. Читай документы проекта, а не только запись:
|
||||
граница домена и «чем проект **не** является» из паспорта отсекают половину
|
||||
вариантов до того, как их начнут сравнивать. **В explore не пишем код.**
|
||||
|
||||
Развилку грумминга **не записывай вопросом** — она и есть предмет следующего
|
||||
шага. Это отличие от обычной ветки: там развилка уходит в запись, здесь она
|
||||
копится в чекпоинт.
|
||||
|
||||
### Р3. Чекпоинт: варианты
|
||||
|
||||
**Остановись и покажи человеку способы решить.** Это первый из двух плановых
|
||||
стопов, и он существует потому, что после `propose` выбор уже сделан
|
||||
предложением.
|
||||
|
||||
Форма — короткая, экран текста:
|
||||
|
||||
- **вопрос**, на который отвечаем, одной фразой (он уже есть в записи);
|
||||
- **2–4 варианта**, не больше. Больше четырёх — это не выбор, а список: человек
|
||||
не сравнит, а признает свою неспособность сравнить и попросит рекомендацию.
|
||||
У каждого варианта: в чём суть простыми словами, **что даёт**, **чего стоит**,
|
||||
**что становится невозможным** (это ловится хуже всего и стоит дороже всего);
|
||||
- **рекомендация с причиной**. Человек чаще соглашается, чем выбирает заново;
|
||||
- что известно **недостоверно** и как это проверить, если проверять дёшево.
|
||||
|
||||
Что нельзя: приносить варианты, различающиеся только реализацией; прятать
|
||||
отвергнутое (отвергнутый вариант с названной причиной — половина будущего ADR);
|
||||
приносить один вариант и называть это выбором.
|
||||
|
||||
**Выбор оседает по адресу.** У `research` это раздел «Куда ляжет ответ». У
|
||||
остальных — `design.md` change, который родится на шаге 2, разделом
|
||||
«рассмотренные варианты». Не в переписку: разговор, из которого ничего не
|
||||
записано, повторяется через месяц целиком.
|
||||
|
||||
Три исхода чекпоинта:
|
||||
|
||||
- **выбран способ** — идёшь на шаг 1 общей ветки;
|
||||
- **ответ и есть исход** — работа кончается знанием: запиши ответ по адресу,
|
||||
доложи исход «знание вместо изменения» и закрой задачу (шаг 11). Провенанс у
|
||||
каждого числа обязателен: число без источника проход ревью обязан читать как
|
||||
условие, а не как замер;
|
||||
- **разведка родила задачи** — исход «оказалась крупнее задачи». Нарезка не твоя
|
||||
работа: отдай список формулировками и остановись.
|
||||
|
||||
## Шаги
|
||||
|
||||
### 1. Прочитать задачу
|
||||
|
||||
Прочитай запись и связанные спеки и черновики.
|
||||
|
||||
Проект даёт задаче **критерии приёмки** — выпиши их сразу: на шаге 2 они уезжают
|
||||
в `tasks.md` change. Файл задачи может быть удалён до коммита, а критерии обязаны
|
||||
его пережить.
|
||||
|
||||
Здесь же проверка на «крупнее задачи»: видно, что одним заходом это не
|
||||
мерджится, — объявляй исход **до** заведения change.
|
||||
|
||||
### 2. Завести change — `opsx:propose`
|
||||
|
||||
Вызови Skill `opsx:propose`. Получаем `proposal.md`, дизайн, дельта-спеки
|
||||
(`ADDED`/`MODIFIED`/`REMOVED Requirements`), `tasks.md`. Каждое `### Requirement`
|
||||
содержит `SHALL`/`MUST`; структурные заголовки английские, сценарии
|
||||
`GIVEN/WHEN/THEN`. Прогони `openspec validate --strict <id>`.
|
||||
|
||||
Критерии приёмки задачи, если они были, копируются в `tasks.md` отдельным блоком.
|
||||
Варианты, разобранные на чекпоинте Р3, — в `design.md`, с причиной отказа по
|
||||
каждому отвергнутому.
|
||||
|
||||
**`proposal.md` пишется так, чтобы его понял человек, не читавший спек.** Это не
|
||||
стилистическое пожелание: из него собирается чекпоинт шага 5, и переписывать его
|
||||
там заново значит завести второй дом для одного объяснения. Требование стоит в
|
||||
`openspec/config.yaml`, `rules.proposal` — то есть применяется в момент
|
||||
порождения артефакта, а не вспоминается после.
|
||||
|
||||
### 3. Разметка задачи — агент `review-scope`
|
||||
|
||||
**Один запуск на всю задачу, и он обслуживает оба чекпоинта ревью.** Запусти
|
||||
агента `review-scope`, дав ему корень проекта, идентификатор change, базу диффа и
|
||||
запись задачи. Кода на этот момент нет, и это условие его работы, а не помеха.
|
||||
|
||||
Он возвращает **план задачи**:
|
||||
|
||||
- **размер** (малое / среднее / крупное) и **сложность** (знакомое /
|
||||
незнакомое), каждое с обоснованием по факту;
|
||||
- **метку** как максимум по двум осям: `small`, `medium` или `large`;
|
||||
- **состав ревью дизайна** — что звать на шаге 4;
|
||||
- **таблицу тем** «тема → дом → глубина → кто закрывает» — для шага 7;
|
||||
- разнесение документов проекта по трём категориям и строку про директивы.
|
||||
|
||||
**Метку выбираешь не ты.** Раньше состав ревью дизайна называл сам оркестратор —
|
||||
то есть тот, кто только что довёл предложение до `propose`. Разведённости с
|
||||
автором в этой точке не было вовсе; теперь есть.
|
||||
|
||||
**План держи в контексте до конца задачи.** На диск он не пишется: файл-план стал
|
||||
бы четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, пережил
|
||||
бы задачу и разошёлся бы с ней молча. Прервался прогон — повтори шаг 3, это самый
|
||||
дешёвый его проход.
|
||||
|
||||
**Разметка повторяется ровно в одном случае** — если правки изменили сами
|
||||
**дельта-спеки**: план выведен из них, и план по отменённым требованиям назовёт
|
||||
не те темы. Во всех прочих случаях, включая переделку формы кода на шаге 7,
|
||||
метка остаётся прежней.
|
||||
|
||||
### 4. Ревью дизайна — ДО кода, состав по метке
|
||||
|
||||
Вызови Skill **`av-dev-code:review`**, дав ссылку на change `<id>`,
|
||||
**план разметки с шага 3** и указание, что это ревью дизайна.
|
||||
|
||||
Состав приходит планом, а не решается здесь:
|
||||
|
||||
| Метка | Проходы на предложении |
|
||||
|---|---|
|
||||
| `small` | `specs` |
|
||||
| `medium` | `specs`, `rubric` |
|
||||
| `large` | `specs`, `rubric`, `architecture` + вопрос автору о трёх формах решения |
|
||||
|
||||
`review-specs` в режиме «дизайн ДО кода» идёт **на каждой задаче**: это самый
|
||||
дешёвый проход конвейера, и он ловит то, что на готовом коде уже не чинят.
|
||||
Остальные включаются меткой, потому что стадия стоит на каждой задаче и каждый
|
||||
лишний проход здесь умножается на число задач.
|
||||
|
||||
Смысл стадии: архитектурная находка на готовом коде стоит переписывания и потому
|
||||
игнорируется — та же находка здесь стоит абзаца обсуждения. Если `review-rubric`
|
||||
запускался, перенеси его рубрику в `tasks.md` как приёмочные критерии; там же уже
|
||||
лежат критерии от постановки, если они были.
|
||||
|
||||
**Отработка замечаний, и она идёт до чекпоинта, а не после:**
|
||||
|
||||
- мелочь и явные улучшения — правь сам в спеках и дизайне;
|
||||
- развилки (компромисс, scope, инвариант) — **не в запись, а в чекпоинт**: он
|
||||
следующим шагом, и это ровно то, ради чего он поставлен здесь;
|
||||
- после правок перепрогони `openspec validate --strict <id>`.
|
||||
|
||||
### 5. Чекпоинт: объяснение
|
||||
|
||||
**Остановись и объясни человеку, что происходит.** Второй плановый стоп и
|
||||
единственный обязательный для всех задач.
|
||||
|
||||
Он стоит **после** ревью дизайна намеренно. Человек читает объяснение, уже
|
||||
просеянное машиной: то, что поймал бы `review-specs`, до него не доходит, а
|
||||
внимание — самый дорогой ресурс процесса, и тратить его на выловимое машиной
|
||||
нельзя.
|
||||
|
||||
**Объяснение не сочиняется заново — оно собирается из артефактов**, `proposal.md`
|
||||
и `design.md`. Третий пересказ был бы третьим домом одного и того же и разошёлся
|
||||
бы с обоими. Что показываешь:
|
||||
|
||||
- **в чём проблема** — словами домена из паспорта, без имён модулей и функций;
|
||||
- **как решаем** — суть одним абзацем. Не пересказ дельта-спек: спека нормирует,
|
||||
а здесь объясняют;
|
||||
- **что человек увидит иначе**, когда это будет сделано;
|
||||
- **чего мы намеренно не делаем** и почему — граница scope ловится хуже всего;
|
||||
- **чем рискуем и что осталось нерешённым** — сюда съезжаются развилки,
|
||||
накопленные до этого места, и находки ревью с пометкой `развилка`;
|
||||
- **что дальше**, если возражений нет.
|
||||
|
||||
Проверка на «простой язык» одна и механическая: **в тексте нет `SHALL`, нет имён
|
||||
файлов и функций там, где вещь называется по-русски, и нет слов, которых нет в
|
||||
паспорте проекта.** Не проходит — переписывай, а не объясняй, почему иначе
|
||||
нельзя.
|
||||
|
||||
Длина — экран. Длинное объяснение не читают, а пролистывают, и чекпоинт
|
||||
превращается в ритуал одобрения.
|
||||
|
||||
Три исхода:
|
||||
|
||||
- **согласен** — идёшь на шаг 6;
|
||||
- **скорректировать** — правишь спеки и дизайн по сказанному. Изменились
|
||||
**дельта-спеки** — повтори шаг 3 (разметка выведена из них) и ту часть ревью
|
||||
дизайна, которой касается правка; затем чекпоинт **заново**. Правка внутри
|
||||
дизайна без спек — повтори только чекпоинт;
|
||||
- **не одобрено** — исход «не доведена» с причиной. Change остаётся
|
||||
незаархивированным, задача не закрывается, ничего не коммитится наполовину.
|
||||
|
||||
### 6. Написать код — `opsx:apply`
|
||||
|
||||
Вызови Skill `opsx:apply` для реализации `tasks.md`. Код — по конвенциям проекта
|
||||
(каталог `docs/conventions/`). Меняешь схему — обнови её описание в документации
|
||||
тем же change, если проект этого требует: гейт обычно это проверяет.
|
||||
|
||||
Прогони гейт и добейся зелёного — он же гейт следующего шага.
|
||||
|
||||
**Поведенческая верификация.** Если задача меняет реальное поведение (новый
|
||||
эндпоинт, разбор входа, схема, форма ответа) — зелёных юнит-тестов мало. Подними
|
||||
изменение вживую командой из раздела команд `CLAUDE.md` и прогони сценарий.
|
||||
Пропусти только для чисто внутренних правок без наблюдаемого рантайма.
|
||||
|
||||
**Сервис не оставляем лежать.** Если запуск упал — почини или откати до конца
|
||||
шага.
|
||||
|
||||
### 7. Ревью кода — та же метка
|
||||
|
||||
Вызови Skill **`av-dev-code:review`**, дав ссылку на change `<id>`,
|
||||
базу диффа, **план разметки с шага 3** и режим запуска.
|
||||
|
||||
**Метку ты не выбираешь, и это правило, а не упрощение.** Её назвал
|
||||
`review-scope` ещё на шаге 3 — по размеру и сложности, с обоснованием по каждой
|
||||
оси. Причина в разведённости: ты только что написал этот код, и решать, насколько
|
||||
глубоко его проверять, тебе нельзя — под давлением «я почти закончил» решение
|
||||
известно заранее. Правило выбора живёт в скилле конвейера —
|
||||
`av-dev-code:review`, `references/review-levels.md`; проектные
|
||||
триггеры — в `docs/review.*`, подраздел «Триггеры метки».
|
||||
|
||||
**Метка не пересматривается по факту диффа.** Дифф может выйти крупнее, чем
|
||||
ожидалось при разметке, — это не повод её поднимать: пересмотр означал бы второй
|
||||
запуск разметчика, ровно то, ради устранения чего он и переехал на шаг 3.
|
||||
|
||||
**Считаешь метку заниженной — скажи это в докладе строкой, а не переспорь.**
|
||||
Разметчик вправе и поднять, и понизить; твоё несогласие это факт для человека, а
|
||||
не команда конвейеру. Место, где такое несогласие превращается в изменение
|
||||
правил, — журнал дефектов `docs/review.md`, и только постфактум.
|
||||
|
||||
**Плана нет — ревью кода не запускается.** Триаж требует план обязательным
|
||||
входом: без него он не может сверить, все ли размеченные темы вернули отчёт, а
|
||||
эта сверка — единственная защита от молчащего пропуска. Потерял план (прервалась
|
||||
сессия, ушёл контекст) — повтори шаг 3, а не гони прогон без него.
|
||||
|
||||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||||
знает свои рёбра: гейт открывает опиниативные проходы, проходы с пометкой «держит
|
||||
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
||||
доказанной), триаж — сток. Просить **`линейно`** нужно только по причине, и она
|
||||
называется строкой: так сказал оператор; машина занята чем-то ещё; идёт разбор
|
||||
самого конвейера.
|
||||
|
||||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||||
покрытия.
|
||||
|
||||
**Сверь план прогона с исходом, прежде чем коммитить.** Отчёт начинается планом
|
||||
разметчика — таблицей «тема → дом → глубина → кто закрывает», — и против каждой
|
||||
темы обязан стоять исход. Тема без отчёта и тема без дома — разные вещи, и обе
|
||||
должны быть названы. Реестр короткий (шесть тем ядра плюс свои) — сверка стоит
|
||||
одного взгляда.
|
||||
|
||||
#### Отработка, и здесь появляется одно новое правило
|
||||
|
||||
Помеченное `инлайн` чини сам и не логируй. `развилка` — вопросом в запись (он уже
|
||||
сформулирован триажем, его остаётся перенести). После правок — снова гейт.
|
||||
|
||||
**Находка, отменяющая одобренный дизайн, отменяет и одобрение.** Признак
|
||||
проверяемый: **меняются ли дельта-спеки**.
|
||||
|
||||
- не меняются — находка внутри дизайна, дожимай сам, это обычная отработка;
|
||||
- меняются — решение стало другим, а одобрено было прежнее. Повтори шаг 3
|
||||
(разметка выведена из дельта-спек) и **вернись на чекпоинт шага 5** с тем, что
|
||||
изменилось и почему.
|
||||
|
||||
**Это правило старше правила о развилке.** Находка класса `развилка`, чьё
|
||||
основание — «надо менять спеку», подпадает под оба; побеждает возврат на
|
||||
чекпоинт, а вопрос в запись при нём остаётся, но возврата не заменяет. Иначе
|
||||
одобренный дизайн переделывался бы записанным вопросом, то есть молча.
|
||||
|
||||
Тихо переделать утверждённое нельзя. Чекпоинт, который можно обойти находкой
|
||||
ревью, не значит ничего, а человек при этом уверен, что одобрил именно то, что
|
||||
уехало в коммит.
|
||||
|
||||
**Урожай — списком, не задачами.** Отложенные находки (реальный `major` не для
|
||||
этого мерджа, развилка, решённая «потом», пачка `nit`) собери в секцию доклада
|
||||
`Урожай`: формулировка, оракул, провенанс. Задачи из него **заводит не этот
|
||||
скилл** — их заводит `av-dev-tasks:tasks` своим сценарием «задачи из ревью и
|
||||
аудита»: своя нарезка, свой формат, свои правила дублей. Твоя обязанность — не
|
||||
потерять и передать.
|
||||
|
||||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
|
||||
### 8. Архивировать — `opsx:archive`
|
||||
|
||||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||||
|
||||
### 9. Синк документации
|
||||
|
||||
**Вызови Skill `av-dev-docs:docs`**: он владеет содержимым документов канона и
|
||||
ведёт чек-лист синка.
|
||||
|
||||
**Правило одно и оно жёсткое: принуждённое отрицание.** Доклад обязан назвать
|
||||
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
|
||||
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
|
||||
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
|
||||
работает только обязательное отрицание.
|
||||
|
||||
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
|
||||
`av-dev-docs:docs`, и копия уже однажды разошлась с оригиналом, потеряв два
|
||||
триггера.
|
||||
|
||||
**Плагина `av-dev-docs` в проекте нет** — путь в его дерево не разрешится ниоткуда,
|
||||
поэтому за списком иди в **свой** reference:
|
||||
[references/project-facts.md](../review/references/project-facts.md)
|
||||
конвейера ревью перечисляет все документы канона с их предметом. Пройди по этому
|
||||
перечню — каждый документ получает строку, отрицание остаётся обязательным.
|
||||
|
||||
**Двух домов в том перечне нет намеренно, а синку они нужны: `docs/adr/` и
|
||||
`docs/research/`.** Проход ревью их не открывает — процессные, — но ADR как раз
|
||||
**главный выход синка**: решение, принятое по ходу задачи, без этой строки
|
||||
теряется систематически. Добавь их к перечню руками: `adr/` — решение с ценой,
|
||||
принятое в этой задаче; `research/` — записка разведки, если ветка была
|
||||
исследовательской.
|
||||
Триггеры при этом ты знаешь хуже, и это называется в докладе строкой: «синк
|
||||
сделан по перечню документов, без списка триггеров — плагина `av-dev-docs` нет».
|
||||
Канона в проекте тоже нет — назови это исходом и предложи `av-dev-docs:canon`.
|
||||
|
||||
### 10. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
|
||||
он, и здесь она не пересказывается. Вызов не разрешился — плагина в проекте нет:
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev-tasks:tasks`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev-tasks`, не ты) — это правки в рабочем
|
||||
дереве, и оставить их незакоммиченными нельзя: закрытие, не доехавшее до основной
|
||||
ветки, оставит задачу открытой молча, а опора «индексы под git показывают, что и
|
||||
когда закрыто» без коммита — пустые слова. Сообщение короткое, про учёт, а не про
|
||||
работу: `закрыта задача <slug>`. Это второй коммит осознанно: правило «одна задача
|
||||
— один осмысленный коммит» про работу, а учёт — не работа.
|
||||
|
||||
Разведка, кончившаяся знанием, закрывается так же — но перед этим убедись, что
|
||||
ответ **записан по названному адресу и закоммичен**. Закрытая разведка без
|
||||
записанного ответа не оставляет следа вообще: файл задачи удалён, ответ был в
|
||||
переписке.
|
||||
|
||||
Плагина в проекте нет — вызов не разрешится. Тогда **ничего не выдумывай**: скажи
|
||||
в докладе, что учёт задач остаётся за владельцем, и назови исход.
|
||||
**У каждого сценария их четыре**, и живут они у сценария:
|
||||
[решение](references/solve.md) — сделана, не доведена, оказалась крупнее задачи,
|
||||
нужна разведка; [разведка](references/research.md) — способ выбран, знание
|
||||
записано, отказ, не доведена.
|
||||
|
||||
Общего исхода нет намеренно. «Сделана» у решения и «знание записано» у разведки —
|
||||
разные вещи с разной приёмкой, и слово, накрывающее оба, скрывало бы именно то,
|
||||
чем прогон кончился.
|
||||
|
||||
## Доклад
|
||||
|
||||
Коротко, и в нём обязательно:
|
||||
Ядро общее, и в нём обязательно:
|
||||
|
||||
- **исход** одним из четырёх слов и, если не «сделана», чем ограничен результат;
|
||||
- **какой сценарий шёл** — решение или разведка, — и почему выбран он;
|
||||
- **исход** одним из четырёх слов своего сценария и, если он не благополучный,
|
||||
чем ограничен результат;
|
||||
- что сделано, какие вопросы записаны и куда;
|
||||
- **что было одобрено на чекпоинте и совпало ли с тем, что уехало в коммит** —
|
||||
расхождение здесь называется прямо, даже если оно мелкое;
|
||||
- ссылка на архивный change и хеш коммита;
|
||||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||||
это доклад приёмщику, а не отметка «принято»;
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, провенанс);
|
||||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||||
запускались и что проверить было невозможно. Доклад без неё сообщает
|
||||
«проверено», не сообщая, что именно.
|
||||
- чего проверить или узнать **не удалось**.
|
||||
|
||||
Сверх ядра каждый сценарий добавляет своё: [solve.md](references/solve.md) —
|
||||
чекпоинт, change, критерии приёмки, урожай и границы покрытия;
|
||||
[research.md](references/research.md) — вопрос и ответ, адреса записи, заведённые
|
||||
задачи, рамки.
|
||||
|
||||
## Тонкости
|
||||
|
||||
- **Не завязывайся на основную ветку и корень репозитория.** Скилл работает в
|
||||
текущем worktree и на текущей ветке: не делай `git checkout`/`switch`, не
|
||||
создавай веток, не пушь.
|
||||
- Обычная задача с очевидным решением проходит **один** чекпоинт, и это норма, а
|
||||
не упрощение. Два чекпоинта — цена незнания, а не признак серьёзности задачи.
|
||||
- Гейт блокирует: пока он красный, опиниативные проходы не запускаются. Чинить и
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Прогон проходит **один** чекпоинт, и это норма, а не упрощение. Два стопа за
|
||||
одну задачу — цена незнания способа, и платится она двумя прогонами, а не одним
|
||||
длинным.
|
||||
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
|
||||
подтверждать механику: чекпоинты — единственные места, где ждут ответа.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
подтверждать механику: чекпоинт — единственное место, где ждут ответа.
|
||||
- **Сценарий назван вслух — значит, его можно оспорить.** Человек, увидевший в
|
||||
первой реплике «иду разведкой, потому что способа не видно», поправит выбор
|
||||
одной фразой; молча выбранный сценарий он поправит через полчаса работы.
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
# Сценарий «разведка»
|
||||
|
||||
Отвечает на вопрос задачи и записывает ответ туда, где он переживёт переписку.
|
||||
Исход — **знание**: уточнённые документы и уточнённые задачи. **Кода этот
|
||||
сценарий не пишет и change не заводит.**
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
ход; общее для обоих сценариев — вход, обращение к соседним плагинам, правило
|
||||
необратимого, доклад — живёт в SKILL.md и тут не пересказывается.
|
||||
|
||||
**Разведка кончается своим исходом, а не переходом к коду.** Выбранный способ
|
||||
реализует сценарий решения, и запускает его **человек**, следующим прогоном по
|
||||
уточнённой записи. Причина не в церемонии: разведка только что переписала
|
||||
постановку, и брать её в работу тем же заходом значит решать за человека, стоит
|
||||
ли делать это сейчас, — а это приоритет, и он не наш.
|
||||
|
||||
## OpenSpec здесь не предпосылка
|
||||
|
||||
**OpenSpec этому сценарию не нужен**, и это единственное место скилла, где он не
|
||||
предпосылка. Разведка не заводит change и не пишет дельта-спеки: её артефакты —
|
||||
документы канона и записи каталога задач. Скилл `opsx:explore` полезен и зовётся,
|
||||
когда плагин в проекте есть; не разрешился — разведка идёт чтением документов,
|
||||
кода и внешних источников, и это говорится строкой доклада, а не отменяет
|
||||
работу.
|
||||
|
||||
## Кого зовёт этот сценарий
|
||||
|
||||
`av-dev-docs:docs` (ответ уезжает в документы канона), `av-dev-tasks:tasks`
|
||||
(задачи заводятся и уточняются), `av-dev-git:commit`. Правило обращения к соседям
|
||||
и ветка «вызов не разрешился» — общие, они в [SKILL.md](../SKILL.md).
|
||||
|
||||
**Отсутствие канона бьёт по разведке сильнее, чем по решению**, и сказать об этом
|
||||
строкой мало: без документов у ответа нет дома, и знание осядет в переписке.
|
||||
Назови исход и предложи `av-dev-docs:canon`; работу не останавливай, но адрес
|
||||
ответа тогда выбираешь сам и говоришь об этом вслух.
|
||||
|
||||
## Что этот сценарий требует от входа
|
||||
|
||||
Вход общий у обоих сценариев (SKILL.md, раздел «Вход»); своего здесь три условия.
|
||||
|
||||
**Паспорт читается раньше кода.** Граница домена и «чем проект **не** является»
|
||||
отсекают половину вариантов до того, как их начнут сравнивать, — а сравнение
|
||||
вариантов и есть работа этого сценария.
|
||||
|
||||
**Сырьё — `research` без раздела «Вопрос» — не берётся.** Исход «не доведена» с
|
||||
причиной «запись это сырьё»: у неё нет вопроса, а разведка без вопроса
|
||||
превращается в чтение всего подряд с отчётом «интересно, но неприменимо».
|
||||
Дописывать вопрос за автора не твоя работа — этим занят штурм сырья в
|
||||
`av-dev-tasks:tasks`. Назови, чего не хватает, и остановись.
|
||||
|
||||
**Разведка пришла текстом — сформулируй вопрос сам одной фразой и покажи
|
||||
формулировку в первой же реплике.** Разведка, чей вопрос не назван вслух,
|
||||
признаётся удавшейся любым результатом.
|
||||
|
||||
## Ход работы
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
in["вход: файл, слаг или текст"]
|
||||
s1["1. вопрос и рамки<br/>сырьё без «Вопроса» — отказ"]
|
||||
s2["2. разведка: документы, код,<br/>внешние источники, opsx:explore"]
|
||||
s3(["3. ЧЕКПОИНТ: варианты<br/>2–4 способа, цена каждого,<br/>что становится невозможным"])
|
||||
s4["4. ответ в документы канона<br/>av-dev-docs:docs"]
|
||||
s5["5. задачи: завести и уточнить<br/>av-dev-tasks:tasks"]
|
||||
s6["6. гейт проекта, затем коммит<br/>av-dev-git:commit"]
|
||||
s7["7. закрыть разведку — av-dev-tasks:tasks,<br/>вторым коммитом учёта"]
|
||||
out["исход назван: знание, задачи,<br/>отказ или «не доведена»"]
|
||||
|
||||
in --> s1 --> s2 --> s3
|
||||
s3 -->|"выбран способ,<br/>отказ или знание"| s4
|
||||
s3 -.->|"вопрос не тот"| s1
|
||||
s4 --> s5 --> s6 --> s7 --> out
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при расхождении
|
||||
прав текст.
|
||||
|
||||
## Плановый стоп сценария
|
||||
|
||||
**До чекпоинта умолчание прежнее — делать, а не спрашивать.** Развилка, найденная
|
||||
по ходу разведки, не задаётся отдельным вопросом: она копится в чекпоинт, который
|
||||
рядом и стоит дёшево.
|
||||
|
||||
Стоп здесь один, и стоит он **перед записью**. Причина в цене: пока варианты
|
||||
живут в контексте, смена решения стоит абзаца; записанный в документы и разложенный
|
||||
на задачи выбор стоит правки документов и разбора беклога. Второго стопа — «покажи,
|
||||
что именно уедет в документы» — нет намеренно: всё, что пишет разведка, лежит в
|
||||
git и читается диффом, а второй стоп на каждой разведке вырождается в ритуал
|
||||
одобрения.
|
||||
|
||||
**Правило необратимого действует и здесь** (SKILL.md, «Когда спрашивать вне
|
||||
чекпоинта»), и разведка обманчива: она кажется безобидной, а замер лезет туда, где
|
||||
живут данные — прогон на боевой базе, запрос к внешнему платному источнику. Здесь
|
||||
ошибка не откатывается правкой текста.
|
||||
|
||||
## Границы: чего разведка не делает
|
||||
|
||||
- **Кодом.** Ни строки, включая «маленький черновик, чтобы проверить». Замер,
|
||||
требующий кода, — это отдельная задача, и её нужно назвать, а не написать по
|
||||
ходу. Исключение ровно одно и оно не про изменение системы: одноразовый
|
||||
**читающий** прогон (запрос, замер, скрипт в песочнице), чей результат уезжает
|
||||
в ответ с провенансом и который ничего не оставляет в репозитории.
|
||||
- **Приоритетом.** Заведённая задача встаёт в конец своей секции; где ей стоять
|
||||
в очереди, решает человек на груминге (`av-dev-tasks:groom`). Разведка, сама
|
||||
ставящая свой исход первым в беклоге, назначает приоритет тому, что только что
|
||||
придумала.
|
||||
- **Форматом задач и документов.** Индексы и документы руками не правятся: их
|
||||
ведут `av-dev-tasks:tasks` и `av-dev-docs:docs`. Твоё — содержание ответа, их —
|
||||
форма и дом.
|
||||
- **Определением ценности.** «Нужно ли это делать вообще» — вопрос человека.
|
||||
Разведка отвечает «как это можно сделать и чего каждый способ стоит».
|
||||
- **Решением задачи.** Выбранный способ реализует сценарий решения, и запускает
|
||||
его человек следующим прогоном. Перейти в него по ходу нельзя — это тот самый
|
||||
переход, ради невозможности которого сценарии и разведены.
|
||||
|
||||
## Наблюдаемые исходы сценария
|
||||
|
||||
Четыре, и каждый обязан быть назван в докладе прямо. Первые три — это те самые
|
||||
«заведены задачи, записано знание, отказ», которыми кончается разведка по
|
||||
определению типа `research`:
|
||||
|
||||
- **способ выбран** — ответ записан, задачи заведены или уточнены, они готовы к
|
||||
взятию. Дальше сценарий решения, следующим прогоном, и запускает его человек;
|
||||
- **знание записано** — вопрос закрыт, задач он не породил: ответ ценен сам по
|
||||
себе (замер, устройство внешнего формата, «так работает и менять не нужно»);
|
||||
- **отказ** — проверили, проблемы нет либо подход отвергнут. **Полноправный
|
||||
исход, а не пустая работа**: «не делаем и вот почему» экономит всю работу,
|
||||
которая иначе была бы сделана. Причина записывается — без неё через квартал
|
||||
разведку закажут заново;
|
||||
- **не доведена** — вопроса нет (сырьё), рамки исчерпаны без ответа, или человек
|
||||
на чекпоинте не одобрил ни одного варианта. Названо, что успели узнать и до
|
||||
какой границы.
|
||||
|
||||
## Определение сделанного для разведки
|
||||
|
||||
У сценария решения оно своё (SKILL.md); здесь — короткое и другое. Разведка
|
||||
сделана, когда верно всё:
|
||||
|
||||
1. **ответ записан по адресу, который назвала задача** — раздел «Куда ляжет
|
||||
ответ». Адреса не было, а вопрос был — ты назначил адрес сам и сказал об этом
|
||||
строкой;
|
||||
2. **у каждого числа провенанс** — команда или условия, которыми оно получено.
|
||||
Число без источника проход ревью обязан читать как условие, а не как замер, и
|
||||
разведка, оставившая голые числа, вредна: по ним будут решать;
|
||||
3. **отвергнутые варианты названы с причиной**. Отвергнутое без причины
|
||||
возвращается на следующей разведке как новая идея;
|
||||
4. задачи, которые исход породил, заведены — или явно сказано, что не породил;
|
||||
5. написанное закоммичено, разведка закрыта.
|
||||
|
||||
## Шаги
|
||||
|
||||
### 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-docs:docs`**: он владеет содержимым документов канона.
|
||||
Передай ему ответ, адрес из шага 1 и провенанс каждого числа — писать содержание
|
||||
за тебя он не будет, но дом, форму и вычитку держит он.
|
||||
|
||||
**Что именно уезжает:**
|
||||
|
||||
- **ответ на вопрос** — по адресу из шага 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-tasks:tasks`.** Он владеет форматом, дедупом и индексами;
|
||||
путь к его скрипту не выясняй и индексы руками не правь.
|
||||
|
||||
Что просишь сделать:
|
||||
|
||||
- **уточнить саму разведку** — если её вопрос по ходу изменился;
|
||||
- **уточнить существующие задачи** — разведка часто отвечает не «что делать», а
|
||||
«что в поставленном неверно»: постановка, границы в разделе «Затрагивает»,
|
||||
критерии приёмки;
|
||||
- **завести новые задачи**, если исход их породил. Формулировки приноси готовыми:
|
||||
заголовок, «зачем», тип, границы. Нарезку на независимо полезные части и
|
||||
проверку на дубли делает он — у него на это свои правила и свой сценарий.
|
||||
|
||||
**Пачку задач показывай списком, прежде чем заводить.** Разведка — самый лёгкий
|
||||
способ надуть беклог: она порождает идеи быстрее, чем кто-либо успевает их
|
||||
оценивать, а заведённая задача живёт, пока её кто-то не выкинет руками.
|
||||
|
||||
Плагина нет — задачи остаются **списком формулировок в докладе**, и это говорится
|
||||
строкой: учёт работ остаётся за владельцем.
|
||||
|
||||
### 6. Гейт и коммит
|
||||
|
||||
**Сперва гейт проекта** — тот же, что гоняет сценарий решения, и по той же
|
||||
причине: разведка только что правила документы канона и индексы задач, а это
|
||||
ровно то, что машина умеет проверить (`docs.py check`, `tasks.py check --dir`,
|
||||
битые ссылки). Красный гейт чинится здесь, а не оставляется следующему прогону:
|
||||
он придёт за код и получит чужую поломку в наследство.
|
||||
|
||||
Гейта в проекте нет — скажи строкой, что записанное не проверял никто.
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
|
||||
он, и здесь она не пересказывается. Вызов не разрешился — напиши сообщение сам и
|
||||
скажи строкой, что форму коммита не сверял никто.
|
||||
|
||||
Одна разведка — один осмысленный коммит: записанный ответ и заведённые задачи
|
||||
уезжают вместе, потому что порознь они полуправда.
|
||||
|
||||
### 7. Закрыть разведку — после коммита, не раньше
|
||||
|
||||
**Вызови Skill `av-dev-tasks:tasks`** и попроси закрыть запись: ответ записан —
|
||||
`close --implemented`, ушла без ответа — `close --reason`, и строка уезжает в
|
||||
кладбище.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы разведку закрытой без единого следа работы, если шаг 6 упадёт. У
|
||||
разведки это опаснее, чем у решения: следом работы там служит код, а здесь —
|
||||
только записанный ответ. Закрытая разведка без него не оставляет следа вообще —
|
||||
файл задачи удалён, ответ был в переписке.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Сообщение короткое, про
|
||||
учёт, а не про работу: `закрыта задача <slug>`. Правило «одна разведка — один
|
||||
коммит» про работу, а учёт — не работа.
|
||||
|
||||
Плагина в проекте нет — **ничего не выдумывай**: скажи в докладе, что учёт задач
|
||||
остаётся за владельцем, и назови исход.
|
||||
|
||||
## Доклад разведки
|
||||
|
||||
Общая форма доклада — в SKILL.md; у разведки он свой, потому что докладывать
|
||||
нечего из того, о чём спрашивают решение (ни метки ревью, ни критериев приёмки,
|
||||
ни архивного change). Коротко, и в нём обязательно:
|
||||
|
||||
- **исход** одним из четырёх слов;
|
||||
- **вопрос и ответ** — по фразе на каждое. Ответ, который не сворачивается во
|
||||
фразу, — признак того, что разведка отвечала не на один вопрос;
|
||||
- **куда записано** — перечнем адресов, а не «документация обновлена»;
|
||||
- **какие задачи заведены и уточнены** — слагами;
|
||||
- **что осталось неизвестным** и чего это стоит: разведка без этой строки
|
||||
сообщает «выяснено», не сообщая, что именно осталось не выяснено;
|
||||
- **рамки**, если они ограничили работу: докуда копали и почему остановились.
|
||||
|
||||
## Тонкости
|
||||
|
||||
- **Ответ «зависит от» — не ответ.** Если разведка кончилась развилкой, её исход
|
||||
— варианты с ценой, а не пересказ обеих сторон без рекомендации.
|
||||
- **Отрицательный результат записывается так же тщательно, как положительный.**
|
||||
Соблазн не писать его велик: кажется, что писать нечего. Через квартал именно
|
||||
этой записи и не хватит.
|
||||
- **Чужую разведку не переоткрывай молча.** Нашёл в `docs/research/` или в
|
||||
`docs/adr/` ответ на свой вопрос — исход «знание записано» со ссылкой, и это
|
||||
лучшая из возможных разведок: она стоила одного чтения.
|
||||
@@ -0,0 +1,411 @@
|
||||
# Сценарий «решение»
|
||||
|
||||
Способ решения известен, спорно только как. Проводит задачу от постановки до
|
||||
закрытия и **пишет код**: цикл 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-docs:docs"]
|
||||
s10["10. коммит работы — av-dev-git:commit"]
|
||||
s11["11. закрыть задачу — av-dev-tasks:tasks,<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-tasks:tasks` своим сценарием «задачи из ревью и
|
||||
аудита»: своя нарезка, свой формат, свои правила дублей. Твоя обязанность — не
|
||||
потерять и передать.
|
||||
|
||||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
|
||||
### 8. Архивировать — `opsx:archive`
|
||||
|
||||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||||
|
||||
### 9. Синк документации
|
||||
|
||||
**Вызови Skill `av-dev-docs:docs`**: он владеет содержимым документов канона и
|
||||
ведёт чек-лист синка.
|
||||
|
||||
**Правило одно и оно жёсткое: принуждённое отрицание.** Доклад обязан назвать
|
||||
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
|
||||
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
|
||||
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
|
||||
работает только обязательное отрицание.
|
||||
|
||||
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
|
||||
`av-dev-docs:docs`, и копия уже однажды разошлась с оригиналом, потеряв два
|
||||
триггера.
|
||||
|
||||
**Плагина `av-dev-docs` в проекте нет** — путь в его дерево не разрешится ниоткуда,
|
||||
поэтому за списком иди в **свой** reference:
|
||||
[references/project-facts.md](../../review/references/project-facts.md)
|
||||
конвейера ревью перечисляет все документы канона с их предметом. Пройди по этому
|
||||
перечню — каждый документ получает строку, отрицание остаётся обязательным.
|
||||
|
||||
**Двух домов в том перечне нет намеренно, а синку они нужны: `docs/adr/` и
|
||||
`docs/research/`.** Проход ревью их не открывает — процессные, — но ADR как раз
|
||||
**главный выход синка**: решение, принятое по ходу задачи, без этой строки
|
||||
теряется систематически. Добавь их к перечню руками: `adr/` — решение с ценой,
|
||||
принятое в этой задаче; `research/` — если по ходу узналось новое о внешнем мире
|
||||
(записку разведки, предшествовавшей задаче, пишет не этот сценарий).
|
||||
Триггеры при этом ты знаешь хуже, и это называется в докладе строкой: «синк
|
||||
сделан по перечню документов, без списка триггеров — плагина `av-dev-docs` нет».
|
||||
Канона в проекте тоже нет — назови это исходом и предложи `av-dev-docs:canon`.
|
||||
|
||||
### 10. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
|
||||
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
|
||||
он, и здесь она не пересказывается. Вызов не разрешился — плагина в проекте нет:
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev-tasks:tasks`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev-tasks`, не ты) — это правки в рабочем
|
||||
дереве, и оставить их незакоммиченными нельзя: закрытие, не доехавшее до основной
|
||||
ветки, оставит задачу открытой молча, а опора «индексы под git показывают, что и
|
||||
когда закрыто» без коммита — пустые слова. Сообщение короткое, про учёт, а не про
|
||||
работу: `закрыта задача <slug>`. Это второй коммит осознанно: правило «одна задача
|
||||
— один осмысленный коммит» про работу, а учёт — не работа.
|
||||
|
||||
Плагина в проекте нет — вызов не разрешится. Тогда **ничего не выдумывай**: скажи
|
||||
в докладе, что учёт задач остаётся за владельцем, и назови исход.
|
||||
|
||||
## Доклад решения
|
||||
|
||||
Общее ядро доклада — в SKILL.md; сверх него сценарий решения обязан назвать:
|
||||
|
||||
- **что было одобрено на чекпоинте и совпало ли с тем, что уехало в коммит** —
|
||||
расхождение здесь называется прямо, даже если оно мелкое;
|
||||
- ссылка на архивный change и хеш коммита;
|
||||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||||
это доклад приёмщику, а не отметка «принято»;
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, провенанс);
|
||||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||||
запускались и что проверить было невозможно. Доклад без неё сообщает
|
||||
«проверено», не сообщая, что именно.
|
||||
|
||||
## Тонкости сценария
|
||||
|
||||
- Гейт блокирует: пока он красный, опиниативные проходы не запускаются. Чинить и
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Стиль правок — заточка под проект и конвенции, right-size, без золочения.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа.** Отложенные находки
|
||||
отдаются **списком**; превращает их в задачи `av-dev-tasks:tasks`, у него на
|
||||
этот вход отдельный сценарий «задачи из ревью и аудита». Плагина нет — урожай
|
||||
остаётся списком в докладе, и это говорится строкой.
|
||||
- **Способ решения ты не выбираешь.** Он приходит известным: из постановки, из
|
||||
разведки, от человека. Выбор между двумя подходами с разной ценой делается в
|
||||
разведке, у своего чекпоинта, — не по ходу этого сценария.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: doc-consistency
|
||||
description: "Сверка документов канона между собой и с openspec: один факт, живущий в двух домах, прямое противоречие между документами (периметр, зависимости, обратимость), поведение системы, осевшее в architecture.md вместо спек, capability без обзора или с пересказом требований, число без провенанса в research, ADR без ссылки на архивный design.md и без парного статуса при замене, заглушка вместо честной строки в пустом слоте. Читает docs/ и openspec/, кода не читает. Отдаёт готовые формулировки и ничего не правит сам. Соответствие документов коду смотрит агент doc-code-drift, язык — doc-wording. Зовётся скиллом av-dev-docs:healthcheck — на весь канон разом; он же зовётся шагом adopt и шагом upgrade. На отдельной задаче и на синке документации не звать. Только чтение."
|
||||
description: "Сверка документов канона между собой и с openspec: один факт, живущий в двух домах, прямое противоречие между документами (периметр, зависимости, обратимость), поведение системы, осевшее в architecture.md вместо спек, capability без обзора или с пересказом требований, число без провенанса в research, ADR без ссылки на источник (архивный design.md либо записка разведки) и без парного статуса при замене, заглушка вместо честной строки в пустом слоте. Читает docs/ и openspec/, кода не читает. Отдаёт готовые формулировки и ничего не правит сам. Соответствие документов коду смотрит агент doc-code-drift, язык — doc-wording. Зовётся скиллом av-dev-docs:healthcheck — на весь канон разом; он же зовётся шагом adopt и шагом upgrade. На отдельной задаче и на синке документации не звать. Только чтение."
|
||||
tools: Read, Grep, Glob
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -23,7 +23,7 @@ color: yellow
|
||||
| Факт | Дом |
|
||||
| --- | --- |
|
||||
| поведение системы | `openspec/specs/<capability>/spec.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` либо записка разведки |
|
||||
| граница домена, «чем не является» | `passport.md` |
|
||||
| инвариант и его severity | `CLAUDE.md` |
|
||||
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
|
||||
@@ -50,7 +50,10 @@ color: yellow
|
||||
`docs/tasks/` на непереехавшем проекте), принадлежит другому плагину и ведётся
|
||||
своим скриптом; не открывай его ни в той форме, ни в другой. Плюс
|
||||
`openspec/changes/archive/`, когда проверяешь ADR: там лежат `design.md`, из
|
||||
которых записи промоутятся.
|
||||
которых записи промоутятся. **Источник у ADR бывает и второй — записка
|
||||
разведки**: решение, принятое без изменения (намеренный отказ, выбор подхода),
|
||||
`design.md` не имеет по построению. Запись без ссылки **на любой из двух** —
|
||||
находка; запись со ссылкой на записку — нет.
|
||||
|
||||
**Кода ты не читаешь.** Разошёлся ли документ с кодом — вопрос агента
|
||||
`doc-code-drift`, и у него для этого другой вход и другая цена.
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Канон документов проекта
|
||||
|
||||
**Версия 12.**
|
||||
**Номер версии здесь не стоит намеренно.** Этот файл описывает канон таким, какой
|
||||
он сейчас, а число живёт в двух домах, которые не расходятся: константа в
|
||||
`docs.py` (её печатает `docs.py version`) и верхняя запись
|
||||
[журнала](changelog.md). Литерал в шапке был третьим и отстал на первом же
|
||||
повышении — версию 13 он пережил, объявляя канон двенадцатым.
|
||||
|
||||
Это **единственный дом определения канона**. Скиллы `init`, `canon` и `docs`
|
||||
читают его, а не пересказывают: три описания одной раскладки разъедутся, и
|
||||
@@ -141,7 +145,7 @@ openspec/
|
||||
|
||||
**Процессный документ — не документ второго сорта.** `adr/` и `research/`
|
||||
проверяются наравне с остальными, но **сверкой документации**, а не прогоном
|
||||
ревью: ADR без ссылки на архивный `design.md`, замена без парного статуса, число
|
||||
ревью: ADR без ссылки на источник, замена без парного статуса, число
|
||||
без провенанса — это работа агентов `doc-consistency` и `doc-code-drift`, и она
|
||||
осталась там же, где была. Изменилось одно: прогон ревью не открывает их как
|
||||
критерий и не судит по ним изменение.
|
||||
@@ -291,8 +295,17 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
### `adr/`
|
||||
|
||||
**ADR — промоут поверх архивных `design.md`, а не второе сочинение.** Запись
|
||||
цитирует решение и ссылается на `openspec/changes/archive/<id>/design.md`.
|
||||
**ADR — промоут поверх уже написанного, а не второе сочинение.** Запись цитирует
|
||||
решение и ссылается на источник. Источников два, и оба законны:
|
||||
|
||||
- **архивный `design.md`** — решение принято по ходу изменения:
|
||||
`openspec/changes/archive/<id>/design.md`. Обычный случай;
|
||||
- **записка разведки** — решение принято разведкой, и change по нему не будет
|
||||
никогда: намеренный отказ, выбор подхода, «проверили и не делаем». У такой
|
||||
работы нет `design.md` по построению, и без второго источника её решение либо
|
||||
не попадало в `adr/` вовсе, либо попадало сочинённым заново.
|
||||
|
||||
Источник называется в записи всегда — по нему видно, чем решение подтверждено.
|
||||
|
||||
Заводится, когда верно одно из трёх:
|
||||
|
||||
@@ -458,7 +471,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
| Факт | Дом |
|
||||
| --- | --- |
|
||||
| поведение системы | `openspec/specs/<capability>/spec.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` либо записка разведки |
|
||||
| граница домена, «чем не является» | `passport.md` |
|
||||
| инвариант и его severity | `CLAUDE.md` |
|
||||
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
|
||||
@@ -513,7 +526,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
| имя файла не kebab-case латиницей; форма имени ADR | транслит в имени — сверх эвристики | `doc-wording` |
|
||||
| битые относительные ссылки | прямое противоречие между документами | `doc-consistency` |
|
||||
| версия канона и её отставание | достаточность честной строки в пустом слоте | `doc-consistency` |
|
||||
| нетронутый плейсхолдер шаблона | ADR без ссылки на `design.md`, замена без парного статуса | `doc-consistency` |
|
||||
| нетронутый плейсхолдер шаблона | ADR без ссылки на источник, замена без парного статуса | `doc-consistency` |
|
||||
| маркеры долга — числом | **протухший факт, разошедшийся с кодом** | `doc-code-drift` |
|
||||
| миграция изменена, а `database.md` нет | зависимость в манифесте, не названная в обзоре | `doc-code-drift` |
|
||||
| capability без упоминания в `architecture.md` | второй способ там, где обзор обещал единственный | `doc-code-drift` |
|
||||
|
||||
@@ -20,6 +20,44 @@ upgrade` идёт по записям снизу вверх от версии п
|
||||
|
||||
---
|
||||
|
||||
## Версия 14 — 2026-08-11
|
||||
|
||||
У ADR стало два законных источника. Прежде запись цитировала только архивный
|
||||
`design.md`, то есть решение, принятое по ходу изменения. Решение, принятое
|
||||
**разведкой** — намеренный отказ, выбор подхода, «проверили и не делаем», — не
|
||||
имеет `design.md` по построению: change по нему не заводится никогда. Триггер
|
||||
канона такое решение ловит («намеренный отказ от очевидного подхода»), а дома у
|
||||
него не было, и оно оседало в записке разведки или в переписке.
|
||||
|
||||
**Что изменилось.** `adr/` принимает второй источник — записку разведки. Правило
|
||||
«промоут, а не второе сочинение» не тронуто: запись по-прежнему цитирует уже
|
||||
написанное и **называет источник**, изменилось только то, что источников два.
|
||||
Следом сказали то же самое: карта домов, разрез проверки `doc-consistency`, вход
|
||||
и устав самого агента, скелеты `docs/adr/README.md` и `docs/adr/template.md`.
|
||||
|
||||
**Почему это версия, а не правка текста.** Два следствия уезжают в репозиторий
|
||||
проекта. По карте домов судит агент согласованности — прежняя редакция читала ADR
|
||||
со ссылкой на записку разведки как нарушение; а скелеты `adr/` лежат в проекте
|
||||
файлами и говорят там от имени канона.
|
||||
|
||||
**Что сделать проекту.**
|
||||
|
||||
1. Ничего с существующими записями: прежние ADR ссылаются на `design.md`, и это
|
||||
по-прежнему верно.
|
||||
2. **Поднять шапку `docs/adr/README.md`**: «промоут поверх архивного `design.md`»
|
||||
→ «промоут поверх уже написанного», с обоими источниками. Точный текст — в
|
||||
[skeletons.md](skeletons.md), раздел `docs/adr/README.md`.
|
||||
3. **Поднять `docs/adr/template.md`**: строка `- **Источник:**` называет два
|
||||
возможных источника.
|
||||
4. `docs/.docs.json`: `"canon": 14`.
|
||||
|
||||
**Чего делать не надо.** Заводить ADR задним числом по старым разведкам. Запись
|
||||
заводится, когда решение принимается, а не когда о нём вспомнили: сочинённое
|
||||
через полгода обоснование — ровно то «второе сочинение», против которого правило
|
||||
и написано.
|
||||
|
||||
---
|
||||
|
||||
## Версия 13 — 2026-08-11
|
||||
|
||||
Служебный файл канона переименован: `docs/.pm.json` → `docs/.docs.json`. Имя
|
||||
|
||||
@@ -200,9 +200,10 @@
|
||||
```markdown
|
||||
# Журнал решений
|
||||
|
||||
Одна запись — одно решение. **ADR это промоут поверх архивного `design.md`**,
|
||||
а не второе сочинение: запись цитирует решение и ссылается на
|
||||
`openspec/changes/archive/<id>/design.md`.
|
||||
Одна запись — одно решение. **ADR это промоут поверх уже написанного**, а не
|
||||
второе сочинение: запись цитирует решение и ссылается на источник —
|
||||
`openspec/changes/archive/<id>/design.md`, а у решения, принятого разведкой без
|
||||
изменения, на её записку.
|
||||
|
||||
## Когда заводить
|
||||
|
||||
@@ -241,7 +242,8 @@
|
||||
# Краткий заголовок решения
|
||||
|
||||
- **Дата:** ГГГГ-ММ-ДД
|
||||
- **Источник:** openspec/changes/archive/<id>/design.md
|
||||
- **Источник:** openspec/changes/archive/<id>/design.md — либо записка разведки,
|
||||
если решение принято без изменения
|
||||
|
||||
Статус ставится тем же полем и только при пересмотре:
|
||||
`- **Статус:** заменено на ADR-…` либо `- **Статус:** устарело`.
|
||||
|
||||
@@ -25,7 +25,7 @@ from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import NoReturn
|
||||
|
||||
CANON_VERSION = 13
|
||||
CANON_VERSION = 14
|
||||
|
||||
OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: docs
|
||||
description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon.
|
||||
description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md или из записки разведки, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon.
|
||||
---
|
||||
|
||||
# Ведение содержимого канона
|
||||
@@ -97,6 +97,13 @@ description: Вести содержимое документов канона
|
||||
**ADR цитирует решение оттуда и ссылается на источник.** Не пересказывает и не
|
||||
сочиняет заново.
|
||||
|
||||
**Второй законный источник — записка разведки**, и приходит он от скилла
|
||||
`av-dev-code:research`: решение, принятое разведкой (намеренный отказ, выбор
|
||||
подхода, «проверили и не делаем»), `design.md` не имеет по построению — change по
|
||||
нему не будет никогда. Промоут при этом тот же: цитата и ссылка, но на записку.
|
||||
Перечень источников закрыт и живёт в [каноне](../canon/references/canon.md),
|
||||
раздел `adr/`.
|
||||
|
||||
**Триггер заведения, форма имени и правило замены — в
|
||||
[каноне](../canon/references/canon.md), раздел `adr/`.** Здесь они не
|
||||
повторяются: копия правила расходится с оригиналом на первой же смене версии
|
||||
@@ -106,9 +113,9 @@ description: Вести содержимое документов канона
|
||||
нет**. Строка «adr/ — не требуется: решение рутинное» и есть то, ради чего
|
||||
чек-лист существует; её отсутствие неотличимо от «забыл посмотреть».
|
||||
|
||||
Порядок работы: открой архивный `design.md` change, найди в `Decisions` то, что
|
||||
проходит триггер, процитируй решение и его причину, сошлись на источник, добавь
|
||||
строку в индекс `docs/adr/README.md` сверху.
|
||||
Порядок работы: открой источник — архивный `design.md` change либо записку
|
||||
разведки, — найди в нём решение, проходящее триггер, процитируй его и причину,
|
||||
сошлись на источник, добавь строку в индекс `docs/adr/README.md` сверху.
|
||||
|
||||
## Чистка `architecture.md`
|
||||
|
||||
|
||||
@@ -65,7 +65,10 @@
|
||||
источники, что заведомо вне.
|
||||
4. **Провести разведку** и **записать ответ по названному адресу**. Числа — с
|
||||
провенансом: с командой или условиями, которыми получены. Число без источника
|
||||
проход ревью обязан читать как условие, а не как замер.
|
||||
проход ревью обязан читать как условие, а не как замер. Проводит её конвейер
|
||||
проекта — в плагине `av-dev-code` это скилл `resolve`, сценарий разведки;
|
||||
плагина нет — разведка ведётся как проект привык, а этот скилл её только
|
||||
заводит и закрывает.
|
||||
5. **Разложить исход на задачи** — если он их родил. Разведка кончается одним из
|
||||
трёх: заведены задачи, записано знание, отказ. **Отказ — полноправный исход**:
|
||||
«проверили, не проблема» экономит работу.
|
||||
|
||||
Reference in New Issue
Block a user