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:
+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`, не
|
||||
создавай веток, не пушь.
|
||||
- Обычная задача с очевидным решением проходит **один** чекпоинт, и это норма, а
|
||||
не упрощение. Два чекпоинта — цена незнания, а не признак серьёзности задачи.
|
||||
- Гейт блокирует: пока он красный, опиниативные проходы не запускаются. Чинить и
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Прогон проходит **один** чекпоинт, и это норма, а не упрощение. Два стопа за
|
||||
одну задачу — цена незнания способа, и платится она двумя прогонами, а не одним
|
||||
длинным.
|
||||
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
|
||||
подтверждать механику: чекпоинты — единственные места, где ждут ответа.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
подтверждать механику: чекпоинт — единственное место, где ждут ответа.
|
||||
- **Сценарий назван вслух — значит, его можно оспорить.** Человек, увидевший в
|
||||
первой реплике «иду разведкой, потому что способа не видно», поправит выбор
|
||||
одной фразой; молча выбранный сценарий он поправит через полчаса работы.
|
||||
|
||||
Reference in New Issue
Block a user