resolve: ревью дизайна снято, разметка переехала за код
Сценарий решения идёт от предложения сразу к чекпоинту и коду: стадия ревью дизайна упразднена целиком, review-scope запускается после apply и меряет размер по диффу, сложность — сверкой обещанных границ с тронутыми. Чекпоинт остался единственным плановым стопом и стоит теперь до кода. review-rubric конвейером не зовётся, слот рубрики в скелете config.yaml снят. Журнал — тема 74.
This commit is contained in:
@@ -427,7 +427,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
**Файл канону не принадлежит, и проверяет его тоже не канон.** Каталог
|
||||
`openspec/` — предпосылка конвейера: без него не работают ни `opsx:propose`, ни
|
||||
ревью дизайна, ни сверка требований. Заводит его, настраивает и **проверяет
|
||||
сверка требований. Заводит его, настраивает и **проверяет
|
||||
форму** скилл `av-dev:code-openspec`: там образец файла, там же скрипт
|
||||
`openspec.py check`. `docs.py` о файле не говорит ничего.
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ OpenSpec уехал в конвейер. Каталог `openspec/` версие
|
||||
канона: `init` его заводил, `adopt` тоже, образец `config.yaml` лежал в скелетах,
|
||||
а отсутствие каталога `docs.py` считал отказом. Разрез был проведён не там. По
|
||||
OpenSpec работает конвейер — без каталога не запускаются ни `opsx:propose`, ни
|
||||
ревью дизайна, ни сверка требований, — а канон документов о нём только
|
||||
сверка требований, — а канон документов о нём только
|
||||
высказывался. Проект, которому конвейер не нужен, получал отказ за отсутствие
|
||||
того, чем не пользуется.
|
||||
|
||||
@@ -290,7 +290,7 @@ OpenSpec работает конвейер — без каталога не за
|
||||
`config.yaml` описан абзацем — а заводил всё это человек руками, и проверялось
|
||||
из перечисленного ничего. Заведение нового проекта проходило мимо: `init`
|
||||
собирал документы канона и оставлял проект без каталога, без которого не работают
|
||||
ни `opsx:propose`, ни ревью дизайна, ни сверка требований.
|
||||
ни `opsx:propose`, ни сверка требований.
|
||||
|
||||
Хуже отсутствия оказался файл из коробки. `openspec init` кладёт `config.yaml`,
|
||||
где `context` и `rules` — закомментированный пример на английском. Такой файл
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
name: code-openspec
|
||||
description: "Завести и настроить OpenSpec в проекте — openspec init --tools claude, замена закомментированного примера в openspec/config.yaml на настройку канонической формы (язык, правила именования capability, придирки валидатора, адреса паспорта и CLAUDE.md), проверка формы своим скриптом openspec.py (имя файла, схема, незаменённый пример, адреса документов, ключи rules против артефактов схемы) и сверка слепка с живой версией инструмента. Использовать, когда в проекте нет каталога openspec/, когда config.yaml остался примером из коробки, когда заводят новый проект или переводят чужой и дошли до шага OpenSpec, а также когда конвейер отказался работать без источника требований. Каталог openspec нужен именно конвейеру: без него не работают ни opsx:propose, ни ревью дизайна, ни сверка требований."
|
||||
description: "Завести и настроить OpenSpec в проекте — openspec init --tools claude, замена закомментированного примера в openspec/config.yaml на настройку канонической формы (язык, правила именования capability, придирки валидатора, адреса паспорта и CLAUDE.md), проверка формы своим скриптом openspec.py (имя файла, схема, незаменённый пример, адреса документов, ключи rules против артефактов схемы) и сверка слепка с живой версией инструмента. Использовать, когда в проекте нет каталога openspec/, когда config.yaml остался примером из коробки, когда заводят новый проект или переводят чужой и дошли до шага OpenSpec, а также когда конвейер отказался работать без источника требований. Каталог openspec нужен именно конвейеру: без него не работают ни opsx:propose, ни сверка требований."
|
||||
---
|
||||
|
||||
# OpenSpec в проекте
|
||||
|
||||
Каталог `openspec/` — **предпосылка конвейера**, а не канона документов. Без него
|
||||
не работают ни `opsx:propose`, ни ревью дизайна, ни `review-specs`: у требований
|
||||
не работают ни `opsx:propose`, ни `review-specs`: у требований
|
||||
не остаётся дома. Поэтому заводит и настраивает его этот скилл — тот, кто по
|
||||
OpenSpec и работает.
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ rules:
|
||||
- "Заголовки и WHEN/THEN/GIVEN — на английском, остальной текст на русском"
|
||||
tasks:
|
||||
- "Критерии приёмки задачи — отдельным блоком и дословно: файл задачи закрытие удалит, критерии обязаны его пережить"
|
||||
- "Рубрика ревью дизайна, если оно её дало, идёт в тот же блок: приёмка судится по одному списку, а не по двум"
|
||||
- "Шаг плана формулируется проверяемо — по нему видно «сделано / не сделано» без суждения"
|
||||
```
|
||||
|
||||
@@ -88,9 +87,8 @@ ADR** — отвергнутый вариант с названной причи
|
||||
**Правила для `tasks` держит тот же скилл, и по той же причине — момент
|
||||
порождения.** `tasks.md` — единственное, что переживает задачу: файл задачи
|
||||
закрытие удаляет, а приёмка потом судится по критериям, которые в него
|
||||
скопированы. Туда же ложится рубрика ревью дизайна, если оно её дало. Записанное
|
||||
в момент порождения не приходится вспоминать шагом позже, когда артефакт уже
|
||||
написан. Блок `context` проект
|
||||
скопированы. Записанное в момент порождения не приходится вспоминать шагом позже,
|
||||
когда артефакт уже написан. Блок `context` проект
|
||||
дополняет своим (стек, разведка, особенности домена), но **адреса паспорта и
|
||||
`CLAUDE.md` обязательны** — отсутствие адреса к существующему документу
|
||||
`openspec.py check` называет отказом.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""Форма `openspec/config.yaml`: проверка проекта и сверка слепка с инструментом.
|
||||
|
||||
Каталог `openspec/` — предпосылка **конвейера**, а не канона документов: без него
|
||||
не работают ни `opsx:propose`, ни ревью дизайна, ни сверка требований. Поэтому и
|
||||
не работают ни `opsx:propose`, ни сверка требований конвейером. Поэтому и
|
||||
проверка формы живёт здесь, рядом со скиллом, который каталог заводит. Раньше она
|
||||
жила в `docs.py`, у скилла канона, и у файла было два владельца: один заводит,
|
||||
другой проверяет.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: code-resolve
|
||||
description: "Взять одну задачу и довести её до закрытия. Одна точка входа, три сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ известен и меняется поведение — сценарий решения: цикл Spec Driven Development (opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие). Способ известен, а спека не меняется (тип chore: тулчейн, зависимости, сборка, гит-хуки, перенос, чистка) — сценарий обслуживания: правка → гейт со сверкой состава проверок → ревью фиксированным планом без change (autotests, operations, плюс conventions, если тронут код) → синк документации → коммит → закрытие; планового стопа нет, change не заводится. Нашлась дельта-спека — задача оказалась шире своего типа: стоп с объяснением простым языком и двумя решениями человека, переформулировать запись в fix или feature и решать её процессом того типа следующим прогоном либо прекратить работу. Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → вычитка написанного → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст постановки: размеченная запись не обязательна — текст берётся так же, как его берёт opsx:propose, и текстом идут все три сценария. Использовать, когда просят взять, сделать или решить задачу — хоть записью из каталога, хоть описанием прямо в разговоре, — обновить зависимости или сборку, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога."
|
||||
description: "Взять одну задачу и довести её до закрытия. Одна точка входа, три сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ известен и меняется поведение — сценарий решения: цикл Spec Driven Development (opsx propose → чекпоинт с объяснением человеческим языком → opsx apply → разметка по диффу → ревью кода → archive → синк документации → коммит → закрытие). Способ известен, а спека не меняется (тип chore: тулчейн, зависимости, сборка, гит-хуки, перенос, чистка) — сценарий обслуживания: правка → гейт со сверкой состава проверок → ревью фиксированным планом без change (autotests, operations, плюс conventions, если тронут код) → синк документации → коммит → закрытие; планового стопа нет, change не заводится. Нашлась дельта-спека — задача оказалась шире своего типа: стоп с объяснением простым языком и двумя решениями человека, переформулировать запись в fix или feature и решать её процессом того типа следующим прогоном либо прекратить работу. Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → вычитка написанного → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст постановки: размеченная запись не обязательна — текст берётся так же, как его берёт opsx:propose, и текстом идут все три сценария. Использовать, когда просят взять, сделать или решить задачу — хоть записью из каталога, хоть описанием прямо в разговоре, — обновить зависимости или сборку, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога."
|
||||
---
|
||||
|
||||
# Работа над одной задачей
|
||||
@@ -31,7 +31,7 @@ description: "Взять одну задачу и довести её до за
|
||||
## Предпосылки
|
||||
|
||||
- **OpenSpec и скиллы `opsx:*` — жёсткая предпосылка сценария решения**, а не
|
||||
опция. На них стоят его шаги 2, 6 и 8, проход `review-specs` и ревью дизайна
|
||||
опция. На них стоят его шаги 2, 4 и 7 и проход `review-specs`
|
||||
(они завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
||||
подключай OpenSpec, а не вырождай цикл сценария; почему ветка деградации здесь
|
||||
@@ -239,8 +239,8 @@ description: "Взять одну задачу и довести её до за
|
||||
человек.
|
||||
|
||||
Обратной смены «решение → обслуживание» нет: задача, заведшая change, доводится
|
||||
циклом решения. Дельта-спеки, оказавшиеся пустыми, — находка ревью дизайна о
|
||||
самой постановке, а не повод свернуть на короткий путь из середины длинного.
|
||||
циклом решения. Дельта-спеки, оказавшиеся пустыми, — повод назвать это на
|
||||
чекпоинте, а не свернуть на короткий путь из середины длинного.
|
||||
|
||||
**Соблазн «разведаю по ходу» живёт именно здесь**, и он дорог тем, что выглядит
|
||||
экономией одного прогона. Разведка внутри решения не имеет своего чекпоинта:
|
||||
@@ -298,9 +298,9 @@ flowchart TD
|
||||
| Работа | Где шаг |
|
||||
| --- | --- |
|
||||
| предложение и дельта-спеки — `opsx:propose` | [solve](references/solve.md), шаг 2 |
|
||||
| правки спек и дизайна по находкам ревью дизайна | [solve](references/solve.md), шаг 4 |
|
||||
| код — `opsx:apply`, вместе с гейтом до зелёного и поведенческой верификацией | [solve](references/solve.md), шаг 6 |
|
||||
| правки по находкам триажа, помеченным `инлайн` | [solve](references/solve.md), шаг 7; [maintain](references/maintain.md), шаг 4 |
|
||||
| правки спек и дизайна по сказанному на чекпоинте | [solve](references/solve.md), шаг 3 |
|
||||
| код — `opsx:apply`, вместе с гейтом до зелёного и поведенческой верификацией | [solve](references/solve.md), шаг 4 |
|
||||
| правки по находкам триажа, помеченным `инлайн` | [solve](references/solve.md), шаг 6; [maintain](references/maintain.md), шаг 4 |
|
||||
| правка оснастки в сценарии обслуживания | [maintain](references/maintain.md), шаг 2 |
|
||||
|
||||
**Остальное остаётся оркестратору, и перечень закрыт:** выбор сценария и стопы,
|
||||
@@ -334,7 +334,7 @@ flowchart TD
|
||||
- **что делать**: файл задачи либо её текст дословно, критерии приёмки,
|
||||
идентификатор change;
|
||||
- **что читать**: `CLAUDE.md`, конвенции проекта, дельта-спеки change;
|
||||
- **находки — дословно**, как их вернул триаж или ревью дизайна, вместе с
|
||||
- **находки — дословно**, как их вернул триаж, вместе с
|
||||
оракулом;
|
||||
- **границы**: правится названное, соседнее не улучшается заодно; развилок агент
|
||||
не решает, задач не заводит, ничего не коммитит и наружу не ходит — правило
|
||||
@@ -380,8 +380,8 @@ flowchart TD
|
||||
## Автономность и плановый стоп
|
||||
|
||||
**У двух сценариев ровно один плановый стоп**, и стоят они в разных местах:
|
||||
у решения — объяснение после ревью дизайна, у разведки — варианты до первого
|
||||
написанного требования. Правило вокруг них общее.
|
||||
у решения — объяснение сразу после предложения и до кода, у разведки — варианты
|
||||
до первого написанного требования. Правило вокруг них общее.
|
||||
|
||||
**У обслуживания планового стопа нет вовсе, и это следствие, а не поблажка.**
|
||||
Один стоп с ожиданием ответа у него всё же есть — по найденной дельта-спеке, — но
|
||||
|
||||
@@ -125,8 +125,8 @@
|
||||
|
||||
**Третьего решения — «доделать как обслуживание» — нет.** Оно и есть то самое
|
||||
молчаливое изменение поведения, против которого стоит весь разрез: под коммитом,
|
||||
заявляющим «поменяли оснастку», уехала бы правка, не прошедшая ни ревью дизайна,
|
||||
ни чекпоинта, и не оставившая следа в спеках.
|
||||
заявляющим «поменяли оснастку», уехала бы правка, не прошедшая ни чекпоинта, ни
|
||||
ревью по метке, и не оставившая следа в спеках.
|
||||
|
||||
**Сделанное не выбрасывается ни при каком из двух решений.** Оно остаётся в
|
||||
рабочем дереве незакоммиченным: при переформулировке уезжает в change следующим
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Способ решения известен, спорно только как. Проводит задачу от постановки до
|
||||
закрытия и **пишет код**: цикл Spec Driven Development с одним плановым стопом —
|
||||
объяснением после ревью дизайна.
|
||||
объяснением сразу после предложения.
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
@@ -11,14 +11,13 @@
|
||||
пересказывается.
|
||||
|
||||
**OpenSpec — жёсткая предпосылка именно этого сценария** (SKILL.md,
|
||||
«Предпосылки»): на нём стоят шаги 2, 6 и 8, проход `review-specs` и ревью
|
||||
дизайна.
|
||||
«Предпосылки»): на нём стоят шаги 2, 4 и 7 и проход `review-specs`.
|
||||
|
||||
Тонкая обёртка над каноническими скиллами `opsx:propose` / `opsx:apply` /
|
||||
`opsx:archive` — их шаги не переизобретаются, а **зовёт их агент**, не ты
|
||||
(SKILL.md, «Кто пишет: письмо уходит агентам»). Ревью — скилл
|
||||
`av-dev:code-review`; он же держит правило выбора метки, а называет её агент
|
||||
`review-scope` — один раз на задачу, для обеих стадий ревью.
|
||||
`review-scope` — один раз на задачу, **после того как код написан**.
|
||||
|
||||
## Ход работы
|
||||
|
||||
@@ -27,21 +26,20 @@ flowchart TD
|
||||
in["сценарий выбран: решение"]
|
||||
s1["1. прочитать задачу<br/>критерии приёмки выписать сразу"]
|
||||
s2["2. opsx:propose — change, дельта-спеки,<br/>tasks.md — агентом"]
|
||||
s3["3. разметка — review-scope:<br/>размер, сложность, метка, план тем"]
|
||||
s4["4. ревью дизайна, состав по метке<br/>+ отработка замечаний агентом"]
|
||||
s5(["5. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
|
||||
s6["6. opsx:apply — код, гейт,<br/>поведенческая верификация — агентом"]
|
||||
s7["7. ревью кода, та же метка<br/>+ отработка замечаний агентом"]
|
||||
s8["8. opsx:archive"]
|
||||
s9["9. синк документации — av-dev:doc-sync"]
|
||||
s10["10. коммит работы — av-dev-git:commit"]
|
||||
s11["11. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
s3(["3. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
|
||||
s4["4. opsx:apply — код, гейт,<br/>поведенческая верификация — агентом"]
|
||||
s5["5. разметка — review-scope по диффу:<br/>размер, сложность, метка, план тем"]
|
||||
s6["6. ревью кода по метке<br/>+ отработка замечаний агентом"]
|
||||
s7["7. opsx:archive"]
|
||||
s8["8. синк документации — av-dev:doc-sync"]
|
||||
s9["9. коммит работы — av-dev-git:commit"]
|
||||
s10["10. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
|
||||
in --> s1
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10 --> s11
|
||||
s3 -.->|"план задачи: та же метка"| s7
|
||||
s5 -.->|"скорректировать:<br/>меняются дельта-спеки"| s3
|
||||
s7 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10
|
||||
s5 -.->|"план задачи: темы и глубины"| s6
|
||||
s3 -.->|"скорректировать:<br/>правка спек и дизайна"| s3
|
||||
s6 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||||
@@ -93,7 +91,7 @@ flowchart TD
|
||||
|
||||
**Постановка пришла текстом** (SKILL.md, «Постановка текстом») — записи нет,
|
||||
читаешь сам текст. Критерии в нём бывают редко: выпиши то, что там есть, а
|
||||
недостающие **предложи на чекпоинте шага 5** и считай их данными только после
|
||||
недостающие **предложи на чекпоинте шага 3** и считай их данными только после
|
||||
ответа человека. Сам себе критерии не проставляешь — правило то же, что и с
|
||||
записью: они приходят снаружи, и подсунуть их себе значит назначить себе приёмку.
|
||||
Человек критериев не назвал — скажи строкой, что задача идёт без них и приёмка
|
||||
@@ -116,7 +114,7 @@ flowchart TD
|
||||
сценарии — `GIVEN/WHEN/THEN`.
|
||||
|
||||
**`proposal.md` и `design.md` после возврата читаешь сам** — из них собирается
|
||||
чекпоинт шага 5, и держать их в контексте это твоя работа, а не переполнение.
|
||||
чекпоинт шага 3, и держать их в контексте это твоя работа, а не переполнение.
|
||||
Кода нет, читать нечего сверх них.
|
||||
|
||||
Ещё две вещи задание называет прямо, иначе их не сделает никто. **Критерии
|
||||
@@ -128,84 +126,21 @@ flowchart TD
|
||||
`design.md`, с причиной отказа по каждому отвергнутому.
|
||||
|
||||
**`proposal.md` пишется так, чтобы его понял человек, не читавший спек.** Это не
|
||||
стилистическое пожелание: из него собирается чекпоинт шага 5, и переписывать его
|
||||
стилистическое пожелание: из него собирается чекпоинт шага 3, и переписывать его
|
||||
там заново значит завести второй дом для одного объяснения. Требование стоит в
|
||||
`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` как приёмочные критерии; там же уже
|
||||
лежат критерии от постановки, если они были.
|
||||
|
||||
**Отработка замечаний, и она идёт до чекпоинта, а не после:**
|
||||
|
||||
- мелочь и явные улучшения — правкой спек и дизайна, и её делает **агент**
|
||||
(SKILL.md, «Кто пишет»): находки уходят ему дословно, вместе с
|
||||
идентификатором change и требованием перепрогнать
|
||||
`openspec validate --strict <id>`;
|
||||
- развилки (компромисс, scope, инвариант) — **не в запись, а в чекпоинт**: он
|
||||
следующим шагом, и это ровно то, ради чего он поставлен здесь. Агенту развилка
|
||||
не отдаётся вовсе: решает её человек, а не тот, кто правит спеку;
|
||||
- возврат агента — адреса тронутых дельт и исход валидации; правленые спеки
|
||||
перечитываешь по адресам, если чекпоинт опирается на изменившееся.
|
||||
|
||||
### 5. Чекпоинт: объяснение
|
||||
### 3. Чекпоинт: объяснение
|
||||
|
||||
**Остановись и объясни человеку, что происходит.** Единственный плановый стоп
|
||||
этого сценария, и он обязателен для всякой задачи.
|
||||
|
||||
Он стоит **после** ревью дизайна намеренно. Человек читает объяснение, уже
|
||||
просеянное машиной: то, что поймал бы `review-specs`, до него не доходит, а
|
||||
внимание — самый дорогой ресурс процесса, и тратить его на выловимое машиной
|
||||
нельзя.
|
||||
Он стоит **сразу после предложения и до кода** — намеренно. Раньше между
|
||||
`propose` и чекпоинтом стояла стадия ревью дизайна, и человек читал объяснение,
|
||||
уже просеянное машиной. Стадию сняли ради времени прогона, и просеивать теперь
|
||||
нечем: человек читает предложение как оно есть. Взамен стоп пришёл **раньше** —
|
||||
коррекция здесь стоит правки спеки, а не переписывания готового кода.
|
||||
|
||||
**Объяснение не сочиняется заново — оно собирается из артефактов**, `proposal.md`
|
||||
и `design.md`. Третий пересказ был бы третьим домом одного и того же и разошёлся
|
||||
@@ -217,7 +152,7 @@ flowchart TD
|
||||
- **что человек увидит иначе**, когда это будет сделано;
|
||||
- **чего мы намеренно не делаем** и почему — граница scope ловится хуже всего;
|
||||
- **чем рискуем и что осталось нерешённым** — сюда съезжаются развилки,
|
||||
накопленные до этого места, и находки ревью с пометкой `развилка`;
|
||||
накопленные до этого места;
|
||||
- **что дальше**, если возражений нет;
|
||||
- **критерии приёмки, если постановка пришла текстом и не назвала их** —
|
||||
предложенными, а не принятыми: человек их подтверждает или правит здесь же.
|
||||
@@ -241,22 +176,24 @@ flowchart TD
|
||||
|
||||
Три исхода:
|
||||
|
||||
- **согласен** — идёшь на шаг 6;
|
||||
- **скорректировать** — правишь спеки и дизайн по сказанному. Изменились
|
||||
**дельта-спеки** — повтори шаг 3 (разметка выведена из них) и ту часть ревью
|
||||
дизайна, которой касается правка; затем чекпоинт **заново**. Правка внутри
|
||||
дизайна без спек — повтори только чекпоинт;
|
||||
- **согласен** — идёшь на шаг 4;
|
||||
- **скорректировать** — правку спек и дизайна по сказанному делает **агент**
|
||||
(SKILL.md, «Кто пишет»): сказанное человеком уходит ему дословно, вместе с
|
||||
идентификатором change и требованием перепрогнать
|
||||
`openspec validate --strict <id>`. Затем чекпоинт **заново** — правленое
|
||||
объяснение читает тот же человек. Разметки на этот момент ещё нет, и повторять
|
||||
здесь нечего: она идёт после кода;
|
||||
- **не одобрено** — исход «не доведена» с причиной. Change остаётся
|
||||
незаархивированным, задача не закрывается, ничего не коммитится наполовину.
|
||||
|
||||
### 6. Написать код — `opsx:apply`
|
||||
### 4. Написать код — `opsx:apply`
|
||||
|
||||
**Код пишет агент, и в его же задании лежит весь этот раздел** (SKILL.md, «Кто
|
||||
пишет»): вызов `opsx:apply` для реализации `tasks.md`, гейт до зелёного,
|
||||
поведенческая верификация. Возврат — адреса тронутого, исход гейта и строка
|
||||
верификации; диффа в нём нет. **Исход гейта возвращается сводкой, путём к логам
|
||||
шагов и отпечатком дерева** (SKILL.md, «Возврат — не длиннее экрана»): его
|
||||
передача на шаг 7 избавляет ревью от второго прогона того же гейта.
|
||||
передача на шаг 6 избавляет ревью от второго прогона того же гейта.
|
||||
|
||||
Код — по конвенциям проекта
|
||||
(каталог `docs/conventions/`). Меняешь схему — обнови её описание в документации
|
||||
@@ -272,23 +209,52 @@ flowchart TD
|
||||
**Сервис не оставляем лежать.** Если запуск упал — агент чинит или откатывает до
|
||||
конца шага; возврат с лежащим сервисом — незакрытый шаг, а не исход.
|
||||
|
||||
### 7. Ревью кода — та же метка
|
||||
### 5. Разметка задачи — агент `review-scope`
|
||||
|
||||
**Один запуск на всю задачу, и он идёт после кода.** Запусти агента
|
||||
`review-scope`, дав ему корень проекта, идентификатор change, базу диффа и запись
|
||||
задачи. Код уже написан, и **дифф — его источник размера**: он видит, сколько
|
||||
мест тронуто на самом деле, а не сколько обещала постановка.
|
||||
|
||||
Он возвращает **план задачи**:
|
||||
|
||||
- **размер** (малое / среднее / крупное) и **сложность** (знакомое /
|
||||
незнакомое), каждое с обоснованием по факту;
|
||||
- **метку** как максимум по двум осям: `small`, `medium` или `large`;
|
||||
- **таблицу тем** «тема → дом → глубина → кто закрывает» — для шага 6;
|
||||
- разнесение документов проекта по трём категориям и строку про директивы.
|
||||
|
||||
**Метку выбираешь не ты, и это правило держится разведённостью.** Код только что
|
||||
написан по твоему заданию, и решать, насколько глубоко его проверять, тебе нельзя:
|
||||
под давлением «я почти закончил» решение известно заранее. Разметчик работу не
|
||||
писал, а обе оси выводит из фактов — из диффа и из постановки, — и обязан назвать
|
||||
признак по каждой.
|
||||
|
||||
**План держи в контексте до конца задачи.** На диск он не пишется: файл-план стал
|
||||
бы четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, пережил
|
||||
бы задачу и разошёлся бы с ней молча. Прервался прогон — повтори шаг 5, это самый
|
||||
дешёвый его проход.
|
||||
|
||||
**Разметка повторяется ровно в одном случае** — если правки изменили сами
|
||||
**дельта-спеки**: план выведен из задачи, и план по отменённым требованиям назовёт
|
||||
не те темы. Во всех прочих случаях, включая отработку находок инлайна на шаге 6,
|
||||
метка остаётся прежней: дифф от правок по находкам растёт, а задача — нет.
|
||||
|
||||
### 6. Ревью кода — по метке разметки
|
||||
|
||||
Вызови Skill **`av-dev:code-review`**, дав ссылку на change `<id>`,
|
||||
базу диффа, **план разметки с шага 3**, режим запуска и **исход гейта с шага 6** —
|
||||
базу диффа, **план разметки с шага 5**, режим запуска и **исход гейта с шага 4** —
|
||||
сводку, путь к логам шагов и отпечаток дерева.
|
||||
|
||||
**Метку ты не выбираешь, и это правило, а не упрощение.** Её назвал
|
||||
`review-scope` ещё на шаге 3 — по размеру и сложности, с обоснованием по каждой
|
||||
оси. Причина в разведённости: ты только что написал этот код, и решать, насколько
|
||||
глубоко его проверять, тебе нельзя — под давлением «я почти закончил» решение
|
||||
известно заранее. Правило выбора живёт в скилле конвейера —
|
||||
`av-dev:code-review`, `references/review-levels.md`; проектные
|
||||
`review-scope` шагом раньше — по размеру и сложности, с обоснованием по каждой
|
||||
оси; причина в разведённости, и она разобрана там же. Правило выбора живёт в
|
||||
скилле конвейера — `av-dev:code-review`, `references/review-levels.md`; проектные
|
||||
триггеры — в `docs/review.*`, подраздел «Триггеры метки».
|
||||
|
||||
**Метка не пересматривается по факту диффа.** Дифф может выйти крупнее, чем
|
||||
ожидалось при разметке, — это не повод её поднимать: пересмотр означал бы второй
|
||||
запуск разметчика, ровно то, ради устранения чего он и переехал на шаг 3.
|
||||
**Метка, названная по диффу, внутри прогона больше не пересматривается.**
|
||||
Разметчик видел дифф целиком и посчитал по нему обе оси; второй запуск на том же
|
||||
дереве вернул бы то же самое.
|
||||
|
||||
**Считаешь метку заниженной — скажи это в докладе строкой, а не переспорь.**
|
||||
Разметчик вправе и поднять, и понизить; твоё несогласие это факт для человека, а
|
||||
@@ -298,7 +264,7 @@ flowchart TD
|
||||
**Плана нет — ревью кода не запускается.** Триаж требует план обязательным
|
||||
входом: без него он не может сверить, все ли размеченные темы вернули отчёт, а
|
||||
эта сверка — единственная защита от молчащего пропуска. Потерял план (прервалась
|
||||
сессия, ушёл контекст) — повтори шаг 3, а не гони прогон без него.
|
||||
сессия, ушёл контекст) — повтори шаг 5, а не гони прогон без него.
|
||||
|
||||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||||
знает свои рёбра: гейт открывает проходы с мнением, проходы с пометкой «держит
|
||||
@@ -329,9 +295,9 @@ flowchart TD
|
||||
проверяемый: **меняются ли дельта-спеки**.
|
||||
|
||||
- не меняются — находка внутри дизайна, дожимай сам, это обычная отработка;
|
||||
- меняются — решение стало другим, а одобрено было прежнее. Повтори шаг 3
|
||||
(разметка выведена из дельта-спек) и **вернись на чекпоинт шага 5** с тем, что
|
||||
изменилось и почему. Такая находка агенту не отдаётся ни при каких условиях:
|
||||
- меняются — решение стало другим, а одобрено было прежнее. **Вернись на чекпоинт
|
||||
шага 3** с тем, что изменилось и почему; дальше задача идёт своим ходом заново —
|
||||
код, разметка, ревью. Такая находка агенту не отдаётся ни при каких условиях:
|
||||
она отменяет одобрение, а это разговор с человеком.
|
||||
|
||||
**Это правило старше правила о развилке.** Находка класса `развилка`, чьё
|
||||
@@ -354,18 +320,18 @@ flowchart TD
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 7
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
|
||||
### 8. Архивировать — `opsx:archive`
|
||||
### 7. Архивировать — `opsx:archive`
|
||||
|
||||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||||
|
||||
### 9. Синк документации
|
||||
### 8. Синк документации
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`**: он владеет содержимым документов канона и
|
||||
ведёт чек-лист синка.
|
||||
@@ -385,7 +351,7 @@ flowchart TD
|
||||
задачу нельзя: документ, заведённый мимо канона, окажется вторым домом ровно
|
||||
тому, что канон потом заведёт своим.
|
||||
|
||||
### 10. Коммит
|
||||
### 9. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
@@ -395,14 +361,14 @@ flowchart TD
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||||
### 10. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 9 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev:task-track`, не ты) — это правки в рабочем
|
||||
@@ -443,8 +409,8 @@ change. Заводить запись задним числом, чтобы её
|
||||
улучшений заодно.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
так, что регулятора у тебя нет: метку выбирает **не ты, а разметчик, и выводит
|
||||
её из диффа**, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа.** Отложенные находки
|
||||
отдаются **списком**; превращает их в задачи `av-dev:task-track`, у него на
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: code-review
|
||||
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после propose: агент review-scope выводит размер и сложность, из их максимума — метка, и раздаёт темы проходам обеих стадий. Метка правит и ревью дизайна (small — только specs; medium — плюс rubric; large — плюс architecture), и ревью кода (small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе). Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает проходы с мнением, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона проекта. Вызывается из скилла av-dev:code-resolve — двумя стадиями: ревью дизайна до кода и ревью кода после apply. Третий вызов идёт от сценария обслуживания: без change и без метки, фиксированным планом (autotests, operations, плюс conventions, если тронут код), разметчик при этом не запускается."
|
||||
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после apply: агент review-scope выводит размер по диффу и сложность по форме решения, из их максимума — метка, и раздаёт темы проходам. Метка правит состав ревью кода: small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе. Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает проходы с мнением, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона проекта. Вызывается из скилла av-dev:code-resolve после apply. Второй вызов идёт от сценария обслуживания: без change и без метки, фиксированным планом (autotests, operations, плюс conventions, если тронут код), разметчик при этом не запускается."
|
||||
---
|
||||
|
||||
# Конвейер ревью
|
||||
@@ -245,6 +245,11 @@ description: "Конвейер ревью изменения, устроенны
|
||||
| `sonnet` | green | scope, autotests, ops | вывод перечислим и сверяется механически |
|
||||
| `opus` | yellow | specs, code, basics, adversary, rubric, architecture, triage | дорога ошибка — ложная либо пропущенная |
|
||||
|
||||
**`rubric` в составе прогона не стоит и в таблице держится за компанию.** Стадия,
|
||||
где он жил, снята: рубрику на задуманный узел он порождает, не видя кода, а
|
||||
конвейер работает по готовому диффу. Устав остаётся для прямого вызова человеком,
|
||||
и модель у него та же — потому строка и не убрана.
|
||||
|
||||
**Цвет charter'а кодирует модель, а не роль прохода.** Это единственное
|
||||
назначение цвета: список агентов читается взглядом, и по нему сразу видно, чем
|
||||
платит прогон. Роль прохода из имени и так понятна, а цвет, розданный по ролям,
|
||||
@@ -272,20 +277,20 @@ charter'а, а модель потом двигает калибровка, и
|
||||
проде, и он тоже не оставляет следа ни в отчёте, ни в границах покрытия. По той
|
||||
же причине, что `specs`, и это дороже всего в конвейере: проход идёт на каждой
|
||||
задаче.
|
||||
- `architecture` — запускается только со старшей меткой, на 5–10% задач, потолок
|
||||
в 3 находки делает его дешёвым по выходу, а находка на предложении стоит абзаца
|
||||
против переписывания на готовом коде. Дёшево × высокое плечо.
|
||||
- `architecture` — запускается только со старшей меткой, на 5–10% задач, и
|
||||
потолок в 3 находки делает его дешёвым по выходу. Его находка дороже прочих по
|
||||
последствиям: второй способ делать то, что уже делается, переписыванием не
|
||||
чинится, а живёт в кодовой базе годами. Дёшево × высокое плечо.
|
||||
|
||||
**`scope` внизу, и это не противоречие, хотя его ошибка расходится дальше всех —
|
||||
теперь ещё дальше, чем прежде.** С переездом разметки к `propose` он правит
|
||||
состав **обеих** стадий и не пересматривается после кода: ошибка метки стоит
|
||||
всей задачи, а не одного прогона. Модель он всё же держит нижнюю, и вот почему.
|
||||
Его работа распадается надвое: разнесение документов по категориям и раздача тем
|
||||
**перечислимы** — план сверяется с `ls docs/` за секунду, пропущенный документ
|
||||
виден без рассуждения. Выбор метки — суждение, но с переходом на две оси оно
|
||||
стало **дважды перечислимым**: размер считается по перечню границ задачи и
|
||||
дельта-спекам, сложность отвечается одним проверяемым признаком («можно ли до
|
||||
работы назвать тронутые узлы»). Плюс три независимых корректора: отрицательный
|
||||
**`scope` внизу, и это не противоречие, хотя его ошибка расходится дальше
|
||||
всех.** Он правит состав всего прогона и внутри прогона не пересматривается:
|
||||
ошибка метки стоит всей проверки задачи, а не одного прохода. Модель он всё же
|
||||
держит нижнюю, и вот почему. Его работа распадается надвое: разнесение документов
|
||||
по категориям и раздача тем **перечислимы** — план сверяется с `ls docs/` за
|
||||
секунду, пропущенный документ виден без рассуждения. Выбор метки — суждение, но с
|
||||
переходом на две оси оно стало **дважды перечислимым**: размер считается по
|
||||
диффу, сложность отвечается одним проверяемым признаком («можно ли было до работы
|
||||
назвать тронутые узлы»). Плюс три независимых корректора: отрицательный
|
||||
тест `small`, правило «спорный случай вниз» и **сигнал о заниженной метке от
|
||||
`code`** — тот идёт при любой метке и видит дифф целиком. Дешёвая модель
|
||||
безопасна ровно потому, что её вывод устроен как список,
|
||||
@@ -325,21 +330,20 @@ charter'а, а модель потом двигает калибровка, и
|
||||
|
||||
## Метки
|
||||
|
||||
**«Стадия» и «ступень» — разные членения, и путать их нельзя.** Стадий ревью
|
||||
две — дизайна и кода, — и они видны снаружи: их зовёт `av-dev:code-resolve` в
|
||||
разных точках цикла. Ступеней внутри прогона кода пять, они нумерованы и наружу
|
||||
не выходят. Перечень осей процесса целиком — [shared/axes.md](../../shared/axes.md).
|
||||
**Ступени нумерованы и наружу не выходят.** Прогон ревью один, и зовёт его
|
||||
`av-dev:code-resolve` после того, как код написан; членение внутри прогона —
|
||||
ступени, и знать их снаружи не нужно. Перечень осей процесса целиком —
|
||||
[shared/axes.md](../../shared/axes.md).
|
||||
|
||||
**Классификация задачи выдаёт ровно одно значение — метку**: `small`, `medium`
|
||||
или `large`. Это **единственный вход, по которому конвейер выбирает
|
||||
исполнителей**: и на дизайне, и на коде состав читается из неё, а не из класса
|
||||
задачи, не из её типа и не из ощущения важности. Метку ставит `review-scope` при
|
||||
разметке задачи; все проходы получают её в задании и обязаны напечатать в своих
|
||||
границах покрытия.
|
||||
исполнителей**: состав читается из неё, а не из класса задачи, не из её типа и не
|
||||
из ощущения важности. Метку ставит `review-scope` при разметке задачи; все
|
||||
проходы получают её в задании и обязаны напечатать в своих границах покрытия.
|
||||
|
||||
**Метка одна на всю задачу и правит обе стадии ревью** — и дизайна, и кода. У
|
||||
изменения нет двух разных «глубин проверки»: величина, из которой выводится
|
||||
состав, — одна и та же пара «размер × сложность», посчитанная один раз.
|
||||
**Метка одна на всю задачу.** У изменения нет двух разных «глубин проверки»:
|
||||
величина, из которой выводится состав, — пара «размер × сложность», посчитанная
|
||||
один раз по готовому диффу.
|
||||
|
||||
**Метка не меняет список тем — она меняет их дом и глубину.** Все темы ядра
|
||||
названы при любой метке; разница в том, против чего их смотрят (дом темы
|
||||
@@ -367,18 +371,12 @@ charter'а, а модель потом двигает калибровка, и
|
||||
```mermaid
|
||||
flowchart TD
|
||||
propose["opsx:propose — change, дельта-спеки, tasks.md"]
|
||||
scope["review-scope — разметка задачи<br/>размер × сложность → МЕТКА"]
|
||||
checkpoint(["чекпоинт: объяснение человеку"])
|
||||
apply["opsx:apply — код, гейт зелёный"]
|
||||
scope["review-scope — разметка по диффу<br/>размер × сложность → МЕТКА"]
|
||||
label{{"метка"}}
|
||||
|
||||
subgraph design["Ревью дизайна — до кода"]
|
||||
dS["specs — всегда"]
|
||||
dR["+ rubric"]
|
||||
dA["+ architecture<br/>+ вопрос автору о трёх формах"]
|
||||
end
|
||||
|
||||
apply["opsx:apply — код, гейт зелёный"]
|
||||
|
||||
subgraph code["Ревью кода — после apply"]
|
||||
subgraph code["Ревью кода"]
|
||||
cGate["autotests — гейт, источник графа"]
|
||||
cS["specs — requirements"]
|
||||
cC["code — conventions + техника"]
|
||||
@@ -389,19 +387,9 @@ flowchart TD
|
||||
cT["triage — единственный сток"]
|
||||
end
|
||||
|
||||
propose --> scope --> label
|
||||
propose --> checkpoint --> apply --> scope --> label
|
||||
|
||||
label -->|small| dS
|
||||
label -->|medium| dR
|
||||
label -->|large| dA
|
||||
dR -.-> dS
|
||||
dA -.-> dR
|
||||
|
||||
dS --> apply
|
||||
dR --> apply
|
||||
dA --> apply
|
||||
|
||||
apply --> cGate
|
||||
label -->|любая метка| cGate
|
||||
cGate -->|зелёный| cS
|
||||
cGate -->|зелёный| cC
|
||||
label -->|small| cInv
|
||||
@@ -418,27 +406,18 @@ flowchart TD
|
||||
cHeavy --> cT
|
||||
```
|
||||
|
||||
Пунктир между проходами дизайна значит «включает предыдущее»: `medium` это
|
||||
`specs` **плюс** `rubric`, `large` — они же плюс `architecture`.
|
||||
Отсюда состав прогона:
|
||||
|
||||
Отсюда состав обеих стадий:
|
||||
|
||||
| Метка | Когда | Ревью дизайна | Ревью кода: ступени | Проходов всего | Доля задач |
|
||||
|---|---|---|---|---|---|
|
||||
| `small` | малое **и** знакомое: багфикс, локальная правка, доки | `specs` | 1, 2, 5 (+3 при своих темах) | **5–6** | **до трети, и меньше, чем `medium`** |
|
||||
| `medium` | **рабочее умолчание**: среднее и знакомое | `specs`, `rubric` | 1, 2, 3, 5 | **7** | **большинство** |
|
||||
| `large` | крупное **или** незнакомое: большой рефакторинг, функциональность, форму которой ещё предстоит нащупать | `specs`, `rubric`, `architecture` | 1, 2, 4, 5 (+3 при своих темах) | **10–11** | **5–10%** |
|
||||
|
||||
Ревью дизайна разбирается отдельно ниже — оно идёт до кода, у него свой плоский
|
||||
граф и свой сток. Здесь оно стоит в таблице потому, что **метка у обеих стадий
|
||||
общая**, и увидеть цену задачи можно только сложив их.
|
||||
| Метка | Когда | Ступени | Проходов | Доля задач |
|
||||
|---|---|---|---|---|
|
||||
| `small` | малое **и** знакомое: багфикс, локальная правка, доки | 1, 2, 5 (+3 при своих темах) | **4–5** | **до трети, и меньше, чем `medium`** |
|
||||
| `medium` | **рабочее умолчание**: среднее и знакомое | 1, 2, 3, 5 | **5** | **большинство** |
|
||||
| `large` | крупное **или** незнакомое: большой рефакторинг, функциональность, форму которой ещё предстоит нащупать | 1, 2, 4, 5 (+3 при своих темах) | **7–8** | **5–10%** |
|
||||
|
||||
**Разметка в этих числах не считается — её платят один раз на задачу, а не один
|
||||
раз на прогон.** Она ушла из состава ревью кода целиком: `review-scope` идёт
|
||||
после `propose`, до ревью дизайна, и его план обслуживает **обе** стадии. Раньше
|
||||
разметка стояла первой в каждом ревью кода, а перед ревью дизайна вызывающий
|
||||
отвечал на тот же вопрос сам — то есть о размере изменения судили дважды и в
|
||||
одном из двух мест без разведённости с автором.
|
||||
раз на прогон.** Она ушла из состава прогона целиком: `review-scope` идёт после
|
||||
`apply`, до первой ступени. Раньше разметка стояла первой в каждом ревью кода и
|
||||
повторялась при каждом перезапуске прогона.
|
||||
|
||||
**Три глубины, и они не про старательность, а про способ доказательства.**
|
||||
**Сверка** — открыть дом темы, открыть дифф, сравнить. **Разбор** — построить
|
||||
@@ -463,8 +442,8 @@ flowchart TD
|
||||
## Порядок прогона — граф, а не очередь
|
||||
|
||||
Метка отвечает «какие темы и на какой глубине», порядок — «что кого ждёт».
|
||||
Стадии остаются единицей **состава**, но порядок задают **не их номера**: между
|
||||
стадиями 2–4 настоящих зависимостей нет — ни один проход не читает вывод другого,
|
||||
Ступени остаются единицей **состава**, но порядок задают **не их номера**: между
|
||||
ступенями 2–4 настоящих зависимостей нет — ни один проход не читает вывод другого,
|
||||
— и очередь между ними была бы платой ни за что.
|
||||
|
||||
Рёбер два вида, и они разной природы. Путать их нельзя: первое про
|
||||
@@ -476,10 +455,10 @@ flowchart TD
|
||||
| **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | гейт → все проходы с мнением; все проходы → триаж |
|
||||
| **конфликт за ресурс** | A и B не держат машину одновременно; кто из них первый — неважно, направления у ребра нет | проходы, помеченные «держит машину» |
|
||||
|
||||
**План разметки — вход графа, а не его узел.** Он готов до того, как ревью кода
|
||||
началось: разметка идёт один раз на задачу, после `propose`. Раньше она была
|
||||
**План разметки — вход графа, а не его узел.** Он готов до того, как прогон
|
||||
начался: разметка идёт один раз на задачу, сразу после `apply`. Раньше она была
|
||||
первым узлом каждого прогона, и ребро «разметка → все» стояло здесь; теперь этого
|
||||
ребра нет, потому что нет и узла.
|
||||
ребра нет, потому что нет и узла — перезапуск прогона разметку не повторяет.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -604,46 +583,48 @@ flowchart TD
|
||||
Режим объявляется в отчёте наравне с меткой: **`по графу`** — одним словом,
|
||||
**`линейно`** — с причиной (какой именно из трёх).
|
||||
|
||||
## Разметка задачи — один раз, до обеих стадий ревью
|
||||
## Разметка задачи — один раз, после кода
|
||||
|
||||
Агент `review-scope`. Идёт **после `propose`, до ревью дизайна**, и один: до его
|
||||
плана неизвестно ни что проверять, ни на какой метке, ни сколько ревьюверов
|
||||
звать на предложение.
|
||||
Агент `review-scope`. Идёт **после `apply`, до первой ступени**, и один: до его
|
||||
плана неизвестно ни что проверять, ни на какой метке, ни сколько проходов звать.
|
||||
|
||||
**Это не стадия прогона, и в счёт проходов метки она не входит.** Раньше
|
||||
разметка была стадией 0 ревью кода и платилась на каждом прогоне, а перед ревью
|
||||
дизайна тот же вопрос — «крупное или незнакомое?» — задавал сам вызывающий, то
|
||||
есть оркестратор, который только что написал предложение. Одна и та же величина
|
||||
считалась дважды, и один из двух раз — без разведённости с автором. Теперь она
|
||||
считается один раз и обслуживает обе стадии.
|
||||
**Это не ступень прогона, и в счёт проходов метки она не входит.** Она платится
|
||||
один раз на задачу: перезапуск прогона по находке «переделать форму» её не
|
||||
повторяет, потому что план описывает задачу, а не дифф.
|
||||
|
||||
**Что он читает.** `docs/` на уровне имён и заголовков, `CLAUDE.md` и
|
||||
`AGENTS.md`, `openspec/specs/`, `docs/review.*` — раздел настройки. Плюс **корпус
|
||||
оценки**: пять письменных источников о задаче, из которых выводятся обе оси.
|
||||
оценки**, и у двух осей он разный.
|
||||
|
||||
| Источник | Размер | Сложность |
|
||||
|---|---|---|
|
||||
| **дифф** | **сколько мест тронуто на самом деле** | — |
|
||||
| запись задачи, «Затрагивает» | перечень границ, названный до работы | узлы названы поимённо — знакомое |
|
||||
| `proposal.md` | что делаем и зачем | вводит ли новое понятие |
|
||||
| `design.md` | какие узлы в решении | **разбирались ли альтернативы** |
|
||||
| `tasks.md` | число шагов и их разнородность | шаг «разобраться», «выяснить» |
|
||||
| дельта-спеки | сколько capability и требований | `ADDED` целой capability против `MODIFIED` |
|
||||
|
||||
**Диффа он не читает: кода ещё нет** — и это причина, по которой корпус должен
|
||||
быть широким. Одни дельта-спеки описывают заказанное поведение, но молчат об
|
||||
объёме работы: шесть шагов в двух узлах видны в `tasks.md`, а факт, что форму
|
||||
решения выбирали из нескольких, — только в `design.md`. Оценка по одному
|
||||
источнику это оценка по остатку.
|
||||
**Размер он меряет по диффу, и это главный источник.** Написанное о задаче до
|
||||
работы описывает заказанное, а не сделанное: перечень границ мог оказаться
|
||||
неполным, а `tasks.md` — обещать шесть шагов там, где хватило двух. Дифф этого не
|
||||
обещает, он это показывает. Прочие источники размер **уточняют**: они называют
|
||||
то, чего в диффе не видно, — например, что тронутые места лежат в разных слоях.
|
||||
|
||||
**Сложность дифф не отвечает вовсе.** Признак незнакомого — нельзя было назвать
|
||||
тронутые узлы до работы, — проверяется сверкой перечня границ задачи с тем, что
|
||||
реально тронуто: разошлись поимённо, значит формы решения не знали. Оттого запись
|
||||
задачи и `design.md` остаются в корпусе и после кода.
|
||||
|
||||
**Расхождение источников по объёму разрешается в пользу большего** — не «спорное
|
||||
вниз»: там ничья при равных данных, здесь один источник просто видел больше.
|
||||
Само расхождение при этом идёт доводом за `незнакомое`: если о задаче написано
|
||||
так, что источники не сходятся в объёме, формы решения не знают.
|
||||
так, что источники не сходятся в объёме, формы решения не знали.
|
||||
|
||||
Возвращает **план задачи**: размер и сложность с обоснованием, метка как
|
||||
максимум по ним, состав ревью дизайна, список тем с домами и глубинами для ревью
|
||||
кода, разнесение документов по трём категориям и строку про найденные директивы.
|
||||
План уезжает в отчёты обеих стадий целиком и служит границами покрытия.
|
||||
максимум по ним, список тем с домами и глубинами, разнесение документов по трём
|
||||
категориям и строку про найденные директивы. План уезжает в отчёт прогона целиком
|
||||
и служит границами покрытия.
|
||||
|
||||
**Он не судит по существу** — ни одной находки об изменении. Его ошибка это
|
||||
пропущенная тема или не та метка, и обе видны: разнесение документов сверяется
|
||||
@@ -660,13 +641,11 @@ flowchart TD
|
||||
повторяется; это самый дешёвый проход конвейера, и платить за его вечность
|
||||
дороже, чем перезапустить.
|
||||
|
||||
**Метка, названная до кода, после кода не пересматривается.** Дифф может выйти
|
||||
крупнее ожидания — метка от этого не двинется. Решение сознательное: пересмотр
|
||||
означал бы либо второй запуск разметчика (ровно то, что здесь убрано), либо
|
||||
машинный порог, который на всякой нетипичной задаче срабатывает не туда.
|
||||
Расхождение факта с разметкой ловится **журналом дефектов** в `docs/review.md`,
|
||||
постфактум, и это единственный сигнал — ровно как и для всякой другой ошибки
|
||||
выбора метки.
|
||||
**Внутри прогона метка не пересматривается.** Разметчик видел дифф целиком, и
|
||||
второй запуск на том же дереве вернул бы то же самое; правки по находкам инлайна
|
||||
дифф растят, а задачу — нет. Ошибка выбора ловится **журналом дефектов** в
|
||||
`docs/review.md`, постфактум, и это единственный сигнал — ровно как и для всякой
|
||||
другой ошибки метки.
|
||||
|
||||
## Прогон без change — сценарий обслуживания
|
||||
|
||||
@@ -683,7 +662,7 @@ change**: у работы, не меняющей поведения, дельт
|
||||
**Прогон ревью идёт в одном из двух режимов, и режим — не глубина.**
|
||||
|
||||
- **С меткой** — обычный прогон по change: разметку сделал `review-scope`, состав
|
||||
обеих стадий выведен из метки.
|
||||
прогона выведен из метки.
|
||||
- **Без метки** — прогон сценария обслуживания: change нет, размечать нечего,
|
||||
план фиксирован и назван сценарием. Разметчик не запускается вовсе.
|
||||
|
||||
@@ -804,7 +783,7 @@ change**: у работы, не меняющей поведения, дельт
|
||||
|
||||
Два прохода, оба против **записанного** критерия. Машину не держат ни один, ребра
|
||||
между ними нет — уходят одним сообщением сразу после зелёного гейта, вместе со
|
||||
стадией 3 или 4 — той, которую назначила метка.
|
||||
ступенью 3 или 4 — той, которую назначила метка.
|
||||
|
||||
- `review-specs` закрывает тему `requirements`. Критерий взят из **дельта-спек
|
||||
предлагаемого изменения**, а не из proposal, сообщения коммита или описания
|
||||
@@ -854,7 +833,7 @@ Recall темы `conventions` равен длине конвенций прое
|
||||
## Ступень 3 — Темы (`medium` целиком; `small` и `large` — только свои темы проекта)
|
||||
|
||||
Агент `review-basics`. Один проход, машину не держит, ничего не запускает и не
|
||||
меряет — уходит одним сообщением вместе со стадией 2, сразу после зелёного гейта.
|
||||
меряет — уходит одним сообщением вместе со ступенью 2, сразу после зелёного гейта.
|
||||
|
||||
**Он не самостоятельная оптика, а держатель тем, у которых с этой меткой нет
|
||||
своего проходчика.** На `medium` это `security`, `operations` и `architecture`:
|
||||
@@ -891,7 +870,7 @@ Recall темы `conventions` равен длине конвенций прое
|
||||
## Ступень 4 — Доказательство (только `large`)
|
||||
|
||||
Три прохода, и все три уходят сразу после зелёного гейта, в одном ряду со
|
||||
стадией 2. Каждый берёт свою тему и доводит её до **доказательства**:
|
||||
ступенью 2. Каждый берёт свою тему и доводит её до **доказательства**:
|
||||
|
||||
- `review-adversary`, тема `security` — находка есть **построенный путь**, а не
|
||||
свойство: он пишет падающий тест и гоняет его;
|
||||
@@ -909,7 +888,7 @@ Recall темы `conventions` равен длине конвенций прое
|
||||
её только прямое слово оператора про эту пару, и тогда в границы покрытия идёт
|
||||
строка, что числа прогона сняты под соседней нагрузкой.
|
||||
|
||||
**Эта стадия зарабатывает больше всех остальных вместе — и она же дороже всех
|
||||
**Эта ступень зарабатывает больше всех остальных вместе — и она же дороже всех
|
||||
остальных вместе.** Измерено на пяти задачах подряд: враждебный проход дал пять из
|
||||
семи выживших находок дозапуска (включая обе верхние); эксплуатационный —
|
||||
единственный, кто нашёл, что откат бинаря поверх новой схемы стартует молча. Оба
|
||||
@@ -927,9 +906,9 @@ Recall темы `conventions` равен длине конвенций прое
|
||||
(эксплуатация и хранилище) — эксплуатационному, `architecture` (устройство,
|
||||
граница домена) — архитектурному. Что с чем сшивать и почему —
|
||||
[project-facts.md](references/project-facts.md), раздел «Сшивать обязаны
|
||||
проходы». Без домов стадия вырождается в общие места.
|
||||
проходы». Без домов ступень вырождается в общие места.
|
||||
|
||||
**Числа и решения проекта эта стадия больше не читает.** `research.*` и `adr.*` —
|
||||
**Числа и решения проекта эта ступень больше не читает.** `research.*` и `adr.*` —
|
||||
процессные документы, и прогон их не открывает. Для эксплуатационного прохода это
|
||||
значит, что **число он обязан снять сам** — замером, а не цитатой из чужой
|
||||
записки; для архитектурного — что граница домена берётся из `passport.*`, а не из
|
||||
@@ -987,85 +966,6 @@ change»: сверять исход с планом триаж обязан и
|
||||
понижение неподтверждённого до гипотезы → отсев вкусовщины → ранжирование по
|
||||
ущербу × вероятности → потолок 7 пунктов в основном списке.
|
||||
|
||||
## Ревью дизайна — до кода
|
||||
|
||||
Запускается на первой стадии ревью (шаг 4 скилла
|
||||
`av-dev:code-resolve`), когда change уже имеет `proposal.md` и
|
||||
дельта-спеки, но кода ещё нет. Разметка задачи к этому моменту уже прошла — она
|
||||
шагом раньше, и метка известна.
|
||||
|
||||
**Состав растёт метками — теми же, что у ревью кода, и по той же паре осей.**
|
||||
Их называет разметка задачи, а не вызывающий: величина считается один раз и
|
||||
служит обеим стадиям.
|
||||
|
||||
| Метка | Проходы на предложении | Проходов |
|
||||
|---|---|---|
|
||||
| `small` — малое и знакомое | `specs` | **1** |
|
||||
| `medium` — среднее и знакомое | `specs`, `rubric` | **2** |
|
||||
| `large` — крупное или незнакомое | `specs`, `rubric`, `architecture` + вопрос автору | **3** |
|
||||
|
||||
- **всегда** — `review-specs` в режиме «дизайн ДО кода». Дельта-спеки сверяются
|
||||
на каждой задаче: это самый дешёвый проход конвейера, и он ловит то, что на
|
||||
готовом коде уже не чинят;
|
||||
- **со `medium`** — `review-rubric`: рубрика на задуманный узел, по ней же
|
||||
разбирается дельта-спека, а сами пункты уезжают приёмочными критериями в
|
||||
`tasks.md`;
|
||||
- **только в `large`** — `review-architecture` на предложении: можно ли выразить
|
||||
существующими понятиями — **включая конструкции стандартной библиотеки**, — не
|
||||
появляется ли второй способ. Вопрос «не изобретаем ли то, что уже есть в
|
||||
библиотеке» живёт здесь; тогда же задаётся вопрос автору дизайна: **«предложи
|
||||
три формы решения и назови компромисс каждой»** — если ответ показывает, что
|
||||
рассматривалась одна, это находка.
|
||||
|
||||
**Рубрика съехала на метку вниз, а архитектура осталась наверху — и это не
|
||||
симметричная правка.** Раньше оба прохода включались одним условием, и `medium`
|
||||
получал на предложении ровно один проход, то есть не отличался от `small` вовсе.
|
||||
Разводятся они потому, что зарабатывают на разном: рубрика порождает **свойства
|
||||
узла** и окупается уже на среднем изменении — её выход уезжает приёмочными
|
||||
критериями в `tasks.md` и работает потом на всей задаче; архитектура отвечает на
|
||||
вопрос «не появился ли второй способ», а он на среднем знакомом изменении
|
||||
отвечается «нет» ещё до запуска. Держать её ниже `large` значит платить за
|
||||
предсказуемый ответ на каждой задаче.
|
||||
|
||||
Причина меток — арифметика, а не экономия на осторожности. Стадия стоит
|
||||
**на каждой задаче**, поэтому каждый проход здесь умножается на число задач, и при
|
||||
мелкой нарезке это самая большая статья конвейера.
|
||||
|
||||
**Граф этой стадии свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
||||
нечего; метка уже названа разметкой задачи; машину не держит ни один проход;
|
||||
сток — не триаж, а шаг скилла `av-dev:code-resolve`, где замечания
|
||||
отрабатываются правкой спек. Триаж здесь не нужен: находок единицы, и каждая
|
||||
либо правит спеку, либо
|
||||
становится развилкой.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
plan[/"план разметки задачи:<br/>размер, сложность, метка"/]
|
||||
proposal["предложение: proposal.md + дельта-спеки"]
|
||||
specs["specs (режим «дизайн ДО кода») — всегда"]
|
||||
rubric["rubric → приёмочные критерии в tasks.md"]
|
||||
arch["architecture на предложении"]
|
||||
author["вопрос автору: три формы решения и компромисс каждой"]
|
||||
fix["шаг resolve: правка спек, развилки — вопросом в запись"]
|
||||
|
||||
plan --> proposal
|
||||
proposal --> specs
|
||||
proposal -->|"метка ≥ medium"| rubric
|
||||
proposal -->|"метка = large"| arch
|
||||
proposal -->|"метка = large"| author
|
||||
specs --> fix
|
||||
rubric --> fix
|
||||
arch --> fix
|
||||
author --> fix
|
||||
```
|
||||
|
||||
Смысл стадии: архитектурная находка на готовом коде стоит переписывания и
|
||||
поэтому игнорируется; та же находка на предложении стоит абзаца обсуждения.
|
||||
|
||||
`rubric` живёт **только** на этой стадии. Судить код по критерию, под который он
|
||||
писался, — корреляция по построению; те же 8–12 свойств уже лежат приёмочными
|
||||
критериями в `tasks.md`.
|
||||
|
||||
## Контракт находок
|
||||
|
||||
Единый для всех проходов — [references/finding-contract.md](references/finding-contract.md).
|
||||
@@ -1185,10 +1085,11 @@ flowchart TD
|
||||
он тратил больше всех остальных проходов вместе, — а не по замеру, который
|
||||
[calibration.md](references/calibration.md) требует перед удалением. Значит и
|
||||
записывается это как сознательное сужение, а не как «класс оказался пустым»:
|
||||
остаток независимого взгляда даёт ревью дизайна (код пишется под его находки) и
|
||||
`architecture` (второй способ, лишние слои), но **альтернативной реализации, с
|
||||
которой можно сдиффить решения, у конвейера теперь нет**. Класс идёт строкой в
|
||||
границы покрытия каждого прогона — там же, где проект перечисляет своё в
|
||||
остаток независимого взгляда даёт `architecture` (второй способ, лишние слои), но
|
||||
**альтернативной реализации, с которой можно сдиффить решения, у конвейера теперь
|
||||
нет**. Сузилось это дважды: вместе с проходом независимой реализации ушла и
|
||||
стадия ревью дизайна, ловившая форму решения до того, как код написан. Класс
|
||||
идёт строкой в границы покрытия каждого прогона — там же, где проект перечисляет своё в
|
||||
подразделе «перестали проверять сознательно».
|
||||
|
||||
Это и есть причина, по которой конвейер готовит ревью, а не заменяет его.
|
||||
|
||||
@@ -42,10 +42,12 @@
|
||||
а именно эта пара и есть рабочее умолчание. Теперь обе оси называются в плане
|
||||
поимённо, и обе — с обоснованием.
|
||||
|
||||
**Оси называются и на стадии дизайна, и на стадии кода — но считаются один
|
||||
раз.** Это и есть причина, по которой разметка переехала к `propose`: состав
|
||||
ревью дизайна выводится из той же пары, что и состав ревью кода, а считать её
|
||||
дважды значит один раз посчитать без разведённости с автором.
|
||||
**Обе оси считаются один раз — по готовому диффу.** Раньше разметка шла до кода,
|
||||
и размер приходилось выводить из написанного о задаче: перечня границ, `tasks.md`,
|
||||
дельта-спек. Теперь размер меряется по тому, что тронуто на самом деле, а
|
||||
написанное о задаче остаётся источником **сложности**: признак незнакомого —
|
||||
нельзя было назвать тронутые узлы заранее — проверяется сверкой обещанного с
|
||||
сделанным.
|
||||
|
||||
**Обратимость — не третья ось, а отрицательный тест.** Она не уточняет размер и
|
||||
не уточняет сложность: она запрещает нижнюю метку независимо от обеих.
|
||||
@@ -105,9 +107,8 @@
|
||||
пределы своего скилла он ходит вызовом, а не файлом.
|
||||
|
||||
Разметка в костяк не входит — она платится один раз на задачу, а не один раз на
|
||||
прогон, и потому **разрез задачи её не удваивает**. Это единственное, что стало
|
||||
дешевле от переезда разметки к `propose`, и это же снимает прежний довод против
|
||||
нарезки.
|
||||
прогон, и потому **перезапуск прогона её не удваивает**. Разрез задачи, впрочем,
|
||||
удваивает: у каждой половины свой дифф, и мерить его приходится порознь.
|
||||
|
||||
**Размер, сложность, метка и глубина объявляются в отчёте, и все четыре с
|
||||
обоснованием.** Метка выбирает `review-scope`; он вправе и поднять, и понизить
|
||||
|
||||
@@ -123,7 +123,7 @@ description: "Завести новый проект — сессия вопро
|
||||
2. Проведи интервью итерациями по ≤3 вопроса.
|
||||
3. **OpenSpec — вызови Skill `av-dev:code-openspec`.** Он заводит каталог и
|
||||
заменяет пример в `config.yaml` настройкой. Делается это **до первого
|
||||
документа**: без `openspec/` не работают ни `opsx:propose`, ни ревью дизайна,
|
||||
документа**: без `openspec/` не работают ни `opsx:propose`,
|
||||
ни сверка требований. Каталог принадлежит конвейеру, а не канону, поэтому
|
||||
здесь только вызов — ни команды, ни формы файла `init` не знает.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user