Compare commits
9
Commits
813345192d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ab759ae4a
|
||
|
|
d79f9d2286
|
||
|
|
8145b378b2
|
||
|
|
a4bc9191e7
|
||
|
|
3c89d7111d
|
||
|
|
daf9f8b824
|
||
|
|
b287cdf71f
|
||
|
|
72d9aa8034
|
||
|
|
17be316634
|
@@ -8,7 +8,7 @@
|
||||
{
|
||||
"name": "av-dev",
|
||||
"source": "./av-dev",
|
||||
"description": "Личный процесс разработки одним плагином: форма раскладки, документы проекта, учёт работ и работа по задачам. Форму держит скилл canon — три операции одной машиной сравнения (check, adopt, upgrade) со скриптом docs.py и общим журналом версий, по которому повышается вся раскладка, включая каталог задач; имя без префикса, потому что форма общая у всех частей. Документы — канон раскладки (CLAUDE.md плюс docs/: паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), заведение нового проекта интервью в doc-init, ведение содержимого по ходу разработки в doc-sync, суд о смысловом здоровье в doc-healthcheck двумя агентами разом. Учёт — задачи каталогом markdown-файлов в task-track: у задачи тип (feature, fix, chore, research), задающий её схему, а у проекта — стадия (build — беклог это план стройки от базы к деталям, порядок строк значит зависимость; support — очередь правок, порядок значит важность); очередь расставляет интерактивный task-groom порядком строк. Работа — одна задача от постановки до закрытия скиллом code-resolve: точка входа одна, сценария три (решение циклом SDD с чекпоинтом, разведка без кода, обслуживание без change), и выбирает сценарий сам скилл, прочитав постановку; плюс конвейер ревью code-review с детерминированным гейтом, сверкой со спеками и обязательным триажем, плюс code-openspec, который заводит и проверяет openspec/. Версия раскладки и настройки живут в .av-dev.toml в корне репозитория. Части включаются следом в проекте, а не установкой: нет docs/ — документы не ведутся, нет каталога задач — учёт остаётся владельцу, нет openspec/ — его заводит сценарий решения. Коммиты — отдельный плагин av-dev-git."
|
||||
"description": "Личный процесс разработки одним плагином: форма раскладки, документы проекта, учёт работ и работа по задачам. Форму держит скилл canon — три операции одной машиной сравнения (check, adopt, upgrade) со скриптом docs.py и общим журналом версий, по которому повышается вся раскладка, включая каталог задач; имя без префикса, потому что форма общая у всех частей. Документы — канон раскладки (CLAUDE.md плюс docs/: паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), заведение нового проекта интервью в doc-init, ведение содержимого по ходу разработки в doc-sync, суд о смысловом здоровье в doc-healthcheck двумя агентами разом. Учёт — задачи каталогом markdown-файлов в task-track: у задачи тип (feature, fix, chore, research), задающий её схему, а у проекта — стадия (build — беклог это план стройки от базы к деталям, порядок строк значит зависимость; support — очередь правок, порядок значит важность); очередь расставляет интерактивный task-groom порядком строк. Работа — одна задача от постановки до закрытия скиллом code-resolve: точка входа одна, сценария три (решение циклом SDD с чекпоинтом, разведка без кода, обслуживание без change), и выбирает сценарий сам скилл, прочитав постановку; плюс конвейер ревью code-review с детерминированным гейтом, сверкой со спеками и обязательным триажем, плюс code-deep-review — глубокое ревью области кода тяжёлыми проходами, которое зовут время от времени, а не на задаче, плюс code-openspec, который заводит и проверяет openspec/. Версия раскладки и настройки живут в .av-dev.toml в корне репозитория. Части включаются следом в проекте, а не установкой: нет docs/ — документы не ведутся, нет каталога задач — учёт остаётся владельцу, нет openspec/ — его заводит сценарий решения. Коммиты — отдельный плагин av-dev-git."
|
||||
},
|
||||
{
|
||||
"name": "av-dev-git",
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
`doc-sync`, `doc-init` и `canon`;
|
||||
- `doc-sync` — содержимое канона по ходу разработки: ADR из архивного
|
||||
`design.md`, промоут конвенций, запись в разведку и журнал ревью, чистка
|
||||
архитектуры.
|
||||
архитектуры. Правки двух родов, и спрашивается один: отражение сделанного
|
||||
пишется молча, новая запись и новая норма — только по слову человека. Он же
|
||||
считает и говорит строкой, сколько задач сделано с прошлой сверки документов.
|
||||
|
||||
**Учёт работ.** Владеет каталогом задач.
|
||||
|
||||
@@ -75,13 +77,13 @@
|
||||
нечего, закрывать нечего, а тип, границы и понимание постановки называются
|
||||
вслух первой репликой — человек, написавший текст, рядом и правит одной фразой.
|
||||
Записи в каталог скилл при этом не заводит ни до работы, ни задним числом.
|
||||
**Решение** идёт циклом SDD с чекпоинтом после ревью дизайна: объяснение
|
||||
человеческим языком, повод скорректировать ход.
|
||||
**Решение** идёт циклом SDD с чекпоинтом сразу после предложения: объяснение
|
||||
человеческим языком, повод скорректировать ход до того, как написан код.
|
||||
**Обслуживание** (тип `chore`: тулчейн и сборка, зависимости, гит-хуки,
|
||||
перенос, чистка) change не заводит и планового стопа не имеет вовсе:
|
||||
дельта-спек у него нет **по построению**, то есть цикл SDD здесь не урезан, а
|
||||
остаётся без входа. Ревью идёт фиксированным планом без метки и без
|
||||
разметчика — `autotests` и `operations`, плюс `conventions` с техническим
|
||||
остаётся без входа. Ревью идёт фиксированным планом без change —
|
||||
`autotests` и `operations`, плюс `conventions` с техническим
|
||||
разбором, если дифф трогает код; главный шаг сценария — синк документации,
|
||||
потому что обслуживание чаще прочих двигает как раз те факты, которые
|
||||
сверяются с кодом. Правка гейта сверяется по составу проверок, а не по цвету.
|
||||
@@ -109,13 +111,23 @@
|
||||
самом скилле только вход, развилка и правила, не зависящие от сценария;
|
||||
- `code-review` — конвейер ревью **по темам**: документ проекта либо заводит
|
||||
тему проверки, либо питает чужую тему источником, либо процессный и в ревью не
|
||||
читается вовсе. Разметка идёт **один раз на задачу**, сразу после `propose`:
|
||||
агент `review-scope` меряет изменение по двум осям — размер и сложность — и
|
||||
берёт метку как максимум по ним. Одна метка правит **обе** стадии ревью:
|
||||
дизайна (`small` — только сверка спек; `medium` — плюс рубрика; `large` — плюс
|
||||
архитектурный проход) и кода (`small` — гейт, спеки, код, триаж; `medium` —
|
||||
плюс приёмник тем; `large` — плюс доказательство: запуск, замер, построенный
|
||||
путь, 5–10% задач). Каждый проход — свой агент, перечень держит сам скилл.
|
||||
читается вовсе. **Состав постоянный, метки у прогона нет:** гейт, сверка со
|
||||
спекой, разбор кода, триаж; приёмник тем идёт, когда у проекта есть свои темы.
|
||||
Цикл задачи проверяет **корректность и механику** против записанного критерия —
|
||||
дельта-спеки, конвенции, инварианты `CLAUDE.md`, вывод инструментов; темы
|
||||
`security`, `operations` и `architecture` закрыты в нём сверкой с записанными
|
||||
инвариантами, и только. Находки по умолчанию чинятся инлайн и молча, человеку
|
||||
уходит необратимое и то, что меняет дельта-спеки, а задачи из урожая заводятся
|
||||
по его слову. Каждый проход — свой агент, перечень держит сам скилл;
|
||||
- `code-deep-review` — **глубокое ревью области**, а не задачи: модуля, слоя,
|
||||
сервиса целиком. Здесь живут тяжёлые проходы, которых в цикле задачи нет, —
|
||||
`review-adversary` строит путь и **прогоняет** падающий тест, `review-ops`
|
||||
снимает числа замером, `architecture` судит форму решения на широком входе;
|
||||
рядом идёт `code` по коду целиком. Исход — не правки, а разговор: находки
|
||||
разбираются с человеком по одной, и согласованное уезжает задачами через
|
||||
`task-track`. Дорого — не на
|
||||
задаче и не по расписанию; вход копит сам цикл строками «отложено» в границах
|
||||
покрытия.
|
||||
|
||||
### av-dev-git
|
||||
|
||||
@@ -133,6 +145,7 @@ flowchart TB
|
||||
direction LR
|
||||
tp["code-resolve<br/>3 сценария: разведка,<br/>решение, обслуживание"] --> rp["code-review<br/>агенты-проходы"]
|
||||
osp["code-openspec<br/>заводит и проверяет openspec/"]
|
||||
deep["code-deep-review<br/>область, а не задача:<br/>тяжёлые проходы"]
|
||||
end
|
||||
canon["canon<br/>форма раскладки всего проекта"]
|
||||
subgraph docsp["документы, владеют содержимым docs/"]
|
||||
@@ -153,7 +166,8 @@ flowchart TB
|
||||
canon --> hc
|
||||
hc --> tasks
|
||||
docs --> rp
|
||||
rp --> tasks
|
||||
rp -.->|"строки «отложено»"| deep
|
||||
deep --> tasks
|
||||
groom -.-> hc
|
||||
opsx["opsx:* — внешний плагин:<br/>explore, propose, apply, archive"]
|
||||
git["av-dev-git: commit"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "av-dev",
|
||||
"description": "Личный процесс разработки одним плагином: форма раскладки, документы проекта, учёт работ и работа по задачам. Форму держит скилл canon — три операции одной машиной сравнения (check, adopt, upgrade) со скриптом docs.py и общим журналом версий, по которому повышается вся раскладка, включая каталог задач; имя без префикса, потому что форма общая у всех частей. Документы — канон раскладки (CLAUDE.md плюс docs/: паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), заведение нового проекта интервью в doc-init, ведение содержимого по ходу разработки в doc-sync, суд о смысловом здоровье в doc-healthcheck двумя агентами разом. Учёт — задачи каталогом markdown-файлов в task-track: у задачи тип (feature, fix, chore, research), задающий её схему, а у проекта — стадия (build — беклог это план стройки от базы к деталям, порядок строк значит зависимость; support — очередь правок, порядок значит важность); очередь расставляет интерактивный task-groom порядком строк. Работа — одна задача от постановки до закрытия скиллом code-resolve: точка входа одна, сценария три (решение циклом SDD с чекпоинтом, разведка без кода, обслуживание без change), и выбирает сценарий сам скилл, прочитав постановку; плюс конвейер ревью code-review с детерминированным гейтом, сверкой со спеками и обязательным триажем, плюс code-openspec, который заводит и проверяет openspec/. Версия раскладки и настройки живут в .av-dev.toml в корне репозитория. Части включаются следом в проекте, а не установкой: нет docs/ — документы не ведутся, нет каталога задач — учёт остаётся владельцу, нет openspec/ — его заводит сценарий решения. Коммиты — отдельный плагин av-dev-git.",
|
||||
"description": "Личный процесс разработки одним плагином: форма раскладки, документы проекта, учёт работ и работа по задачам. Форму держит скилл canon — три операции одной машиной сравнения (check, adopt, upgrade) со скриптом docs.py и общим журналом версий, по которому повышается вся раскладка, включая каталог задач; имя без префикса, потому что форма общая у всех частей. Документы — канон раскладки (CLAUDE.md плюс docs/: паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), заведение нового проекта интервью в doc-init, ведение содержимого по ходу разработки в doc-sync, суд о смысловом здоровье в doc-healthcheck двумя агентами разом. Учёт — задачи каталогом markdown-файлов в task-track: у задачи тип (feature, fix, chore, research), задающий её схему, а у проекта — стадия (build — беклог это план стройки от базы к деталям, порядок строк значит зависимость; support — очередь правок, порядок значит важность); очередь расставляет интерактивный task-groom порядком строк. Работа — одна задача от постановки до закрытия скиллом code-resolve: точка входа одна, сценария три (решение циклом SDD с чекпоинтом, разведка без кода, обслуживание без change), и выбирает сценарий сам скилл, прочитав постановку; плюс конвейер ревью code-review с детерминированным гейтом, сверкой со спеками и обязательным триажем, плюс code-deep-review — глубокое ревью области кода тяжёлыми проходами, которое зовут время от времени, а не на задаче, плюс code-openspec, который заводит и проверяет openspec/. Версия раскладки и настройки живут в .av-dev.toml в корне репозитория. Части включаются следом в проекте, а не установкой: нет docs/ — документы не ведутся, нет каталога задач — учёт остаётся владельцу, нет openspec/ — его заводит сценарий решения. Коммиты — отдельный плагин av-dev-git.",
|
||||
"author": {
|
||||
"name": "Anton Vakhrushev",
|
||||
"email": "anwinged@gmail.com"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-adversary
|
||||
description: "Враждебный проход ревью — не проверяет свойства, а строит путь: «ты контролируешь вход целиком — выведи запись за пределы песочницы»; «ты шлёшь запрос и хочешь, чтобы данные не доехали или испортились — построй такой вход»; «ты можешь повторить и переставить любую операцию — что ломается»; «доведи чувствительное до места, где его быть не должно». Находка — построенный путь с шагами, а не наблюдение. Свойства без пути идут в отдельную секцию и не получают critical. Модель угроз берётся из docs/security.md проекта. Запускается только с меткой large — на изменении, которое не крупное и не незнакомое, построенного пути он не находит, а стоит дорого. Только чтение."
|
||||
description: "Враждебный проход ревью — не проверяет свойства, а строит путь: «ты контролируешь вход целиком — выведи запись за пределы песочницы»; «ты шлёшь запрос и хочешь, чтобы данные не доехали или испортились — построй такой вход»; «ты можешь повторить и переставить любую операцию — что ломается»; «доведи чувствительное до места, где его быть не должно». Находка — построенный путь с шагами, а не наблюдение. Свойства без пути идут в отдельную секцию и не получают critical. Модель угроз берётся из docs/security.md проекта. Зовётся скиллом av-dev:code-deep-review, и только им: вход — названная область кода, а не дифф задачи, глубина постоянная — доказательство. В цикле задачи тему security держит проход review-code сверкой с записанными инвариантами CLAUDE.md, и разбора там нет вовсе. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -22,15 +22,25 @@ color: yellow
|
||||
падающий тест, которым ты доказываешь путь, воспроизводим — и ссылка на него
|
||||
законный оракул.
|
||||
|
||||
**Тебя запускают только с меткой `large`** — на изменении крупном или незнакомом,
|
||||
и это 5–10% задач. Причина в цене прогона, а не в ценности находок: ты держишь
|
||||
машину и идёшь цепочкой, то есть стоишь часов на каждой задаче, где запущен. С
|
||||
меткой `medium` твою половину, отвечаемую **чтением**, задаёт `review-basics`;
|
||||
**на `small` не задаёт никто** — там тему `security` закрывает `review-code`
|
||||
сверкой с записанными инвариантами `CLAUDE.md`, потолком 1 находка на три темы
|
||||
разом. Построенные пути ниже `large` не строит никто ни при одной метке — и так и
|
||||
написано в границах покрытия каждого такого прогона. Значит, раз тебя позвали, стройте путь до конца: сокращать
|
||||
себя «ради скорости» тебе нечем, скорость уже оплачена выбором метки.
|
||||
**Тебя зовёт скилл `av-dev:code-deep-review`, и только он.** В цикле задачи тебя
|
||||
нет: ты держишь машину и стоишь часов, а ценность эта оплачивалась на каждой
|
||||
задаче, где ты запускался, и получалась на немногих. Глубокий прогон идёт по
|
||||
**названной области кода** — модулю, слою, сервису, — время от времени и по
|
||||
решению человека.
|
||||
|
||||
**Отсюда твой вход: область, а не дифф.** Ты судишь написанное, а не изменение, и
|
||||
«тронутые строки» тебе границей не служат. В задании приходят адреса области, дом
|
||||
темы, история места и **отложенные строки** — то, что проходы цикла задачи не
|
||||
смогли доказать и назвали работой для тебя.
|
||||
|
||||
**Задачи здесь нет, и глубина у тебя одна — доказательство.** Раз тебя позвали,
|
||||
строй путь до конца: сокращать себя «ради скорости» тебе нечем, время уже
|
||||
оплачено решением звать глубокий прогон.
|
||||
|
||||
**В цикле задачи тему `security` держит `review-code`** — сверкой диффа с
|
||||
записанными инвариантами `CLAUDE.md`, потолком 1 находка на три темы разом. Это
|
||||
не облегчённая версия тебя, а другой дом темы: свойства, которого нет в
|
||||
инвариантах, там не спросит никто, и разбора этой темы в цикле нет вовсе.
|
||||
|
||||
## Модель угроз — из `docs/security.md`, и не расширяй её самовольно
|
||||
|
||||
@@ -64,7 +74,7 @@ color: yellow
|
||||
**Вопросы адресованы теме, а не тебе по имени.** В `docs/review.md` ты ищешь
|
||||
строки вида `security: <вопрос>`, а не блок `adversary`. Раньше здесь стоял поиск
|
||||
по имени прохода, и это ломалось ровно тем способом, против которого правило и
|
||||
введено: проход переезжает между метками, а вопрос остаётся адресованным его
|
||||
введено: проход переезжает между скиллами, а вопрос остаётся адресованным его
|
||||
имени и перестаёт задаваться молча.
|
||||
|
||||
**Измеренных объёмов проекта у тебя нет.** `docs/research/` — процессный
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-architecture
|
||||
description: "Архитектурный проход ревью — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими (включая конструкции стандартной библиотеки), не появился ли второй способ делать то, что уже делается, не размывается ли граница домена. Потолок 3 находки плюс секция «дешевле переделать до мерджа». Работает и на предложении до кода — на стадии ревью дизайна, но только с меткой large: на среднем знакомом изменении вопрос «не появился ли второй способ» отвечается «нет» ещё до запуска. Решения проекта из docs/adr/ не читает — это процессный документ. Только чтение."
|
||||
description: "Архитектурный проход ревью — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими (включая конструкции стандартной библиотеки), не появился ли второй способ делать то, что уже делается, не размывается ли граница домена. Потолок 3 находки плюс секция «дешевле переделать до мерджа». Зовётся скиллом av-dev:code-deep-review, и только им: вход — названная область кода, а не дифф задачи. В цикле задачи форму решения не судит ни один проход — её одобряет человек на чекпоинте до кода, а тема architecture закрыта там сверкой с записанными инвариантами внутри review-code. Решения проекта из docs/adr/ не читает — это процессный документ. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -10,19 +10,20 @@ color: yellow
|
||||
судить об архитектуре: он не знает, какие понятия в проекте уже есть и как они
|
||||
называются. Поэтому твой вход шире, и первое, что ты делаешь, — его собираешь.
|
||||
|
||||
**Тебя запускают не на каждой задаче, а с меткой `large` — это 5–10% задач.**
|
||||
Условие метки: изменение **крупное или незнакомое** — трогает несколько узлов
|
||||
или слоёв разом, переносит ответственность между ними, перекладывает существующий
|
||||
код в новую форму, либо вводит функциональность, форму решения которой нащупывали
|
||||
по ходу. Ни миграция схемы, ни изменение публичного контракта сами по себе тебя не
|
||||
зовут: там работы для тебя нет, её делают `autotests`, `basics` и `specs`. Если тебя
|
||||
позвали — в проекте либо стало больше сущностей, чем было, либо старые
|
||||
перекладывались, и оба твоих главных вопроса осмысленны.
|
||||
**Тебя зовёт скилл `av-dev:code-deep-review`, и только он.** В цикле задачи тебя
|
||||
нет: вход шире диффа собирается командой проекта, а суждение о форме решения
|
||||
стоит разговора с человеком, и разговор этот цикл не ведёт. Прогон идёт по
|
||||
**названной области кода** — модулю, слою, сервису, — время от времени и по
|
||||
решению человека.
|
||||
|
||||
Мелкую осадку твоих вопросов 2 и 5 — второй способ рядом с диффом и что отсюда
|
||||
удалить — с меткой `medium` задаёт `review-basics`, грепом против единых точек
|
||||
проекта и без карты. Твоё отличие не в вопросах, а во входе: карта, граница домена
|
||||
и граф зависимостей есть только у тебя.
|
||||
**Отсюда твой вход: область, а не дифф.** Ты судишь написанное целиком, и
|
||||
«тронутые строки» тебе границей не служат.
|
||||
|
||||
**В цикле задачи форму решения не судит никто.** Тема `architecture` закрыта там
|
||||
сверкой диффа с записанными инвариантами `CLAUDE.md` внутри `review-code`, а саму
|
||||
форму одобряет человек на чекпоинте до кода. Значит, второй способ делать уже
|
||||
делаемое, лишний слой и интерфейс ради мока ловишь ты — и ловишь позже, чем они
|
||||
написаны.
|
||||
|
||||
Находки — по контракту
|
||||
`${CLAUDE_PLUGIN_ROOT}/skills/code-review/references/finding-contract.md`
|
||||
@@ -130,13 +131,6 @@ grep по именам концепций) и скажи об этом в гра
|
||||
Эта секция может быть непустой даже когда находок нет: «переделать дешевле
|
||||
сейчас» ≠ «сделано неправильно».
|
||||
|
||||
## На стадии ревью дизайна (кода ещё нет)
|
||||
|
||||
Вход — `proposal.md`, `design.md`, дельта-спеки плюс та же карта. Вопросы те же,
|
||||
но ответ стоит абзаца обсуждения, а не переписывания. Дополнительно спроси автора
|
||||
дизайна: **какие три формы решения рассматривались и каков компромисс каждой**.
|
||||
Если рассматривалась одна — это находка сама по себе.
|
||||
|
||||
## Чего этот проход принципиально не может поймать
|
||||
|
||||
- Дефекты внутри реализации: правильность алгоритма, обработку ошибок, граничные
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-autotests
|
||||
description: "Тема `autotests` — проверено ли машиной и хватает ли проверок. Запускает команду гейта проекта (сборка/vet/линт/формат/тесты/флаки/гонки/покрытие изменённых строк/миграции/секреты/уязвимости) и интерпретирует вывод. Отличает новые отказы от унаследованных, находит отсутствующую верификацию (изменённые строки без покрытия, конкурентность без теста, флаки). Пока гейт красный, проходы с мнением не запускаются. Первый проход ревью кода и источник его графа, обязателен при любой метке."
|
||||
description: "Тема `autotests` — проверено ли машиной и хватает ли проверок. Гонит команду гейта проекта (сборка/vet/линт/формат/тесты/флаки/гонки/покрытие изменённых строк/миграции/секреты/уязвимости) и интерпретирует вывод; прогон, сделанный до ревью, засчитывает по отпечатку рабочего дерева вместо повтора. Отличает новые отказы от унаследованных, находит отсутствующую верификацию (изменённые строки без покрытия, конкурентность без теста, флаки). Пока гейт красный, проходы с мнением не запускаются. Первый проход ревью кода и источник его графа, обязателен на всяком прогоне."
|
||||
tools: Bash, Read, Grep, Glob
|
||||
model: sonnet
|
||||
color: green
|
||||
@@ -40,15 +40,42 @@ color: green
|
||||
`CLAUDE.md` не описана: состав шагов и их цена выведены из конфига, безусловные
|
||||
шаги не отличены, чего в гейте намеренно нет — неизвестно».
|
||||
|
||||
## Прогнан ли гейт уже
|
||||
|
||||
**Задача приходит на ревью с зелёным гейтом:** сценарий, приведший её сюда,
|
||||
довёл его до зелёного сам. Второй прогон на неизменившемся дереве вернёт тот же
|
||||
вывод, а стоит он минут — правило и его причина в SKILL.md конвейера, ступень 1.
|
||||
|
||||
Задание несёт сводку прошлого прогона, путь к логам шагов и **отпечаток дерева**,
|
||||
снятый сразу после него. Сними отпечаток сам и сверь:
|
||||
|
||||
<!-- копия: отпечаток-дерева из av-dev/skills/code-review/SKILL.md -->
|
||||
|
||||
```sh
|
||||
{ git rev-parse HEAD; git status --porcelain -uall; git diff HEAD;
|
||||
git ls-files -o --exclude-standard -z | xargs -0 -r git hash-object; } | sha1sum
|
||||
```
|
||||
|
||||
<!-- /копия: отпечаток-дерева -->
|
||||
|
||||
**Совпал** — команду не запускай: читай готовую сводку и логи шагов, а тему
|
||||
закрывай целиком, как обычно. **Разошёлся, отпечатка в задании нет, логи
|
||||
недоступны** — гони гейт сам и ни у кого не спрашивай.
|
||||
|
||||
Переиспользованный прогон объявляется строкой сводки и строкой границ покрытия:
|
||||
чем гейт прогнан, когда и на каком отпечатке.
|
||||
|
||||
## Что делаешь
|
||||
|
||||
1. Определи базу диффа: из задания, иначе `git merge-base HEAD <основная ветка>`
|
||||
(на основной ветке — `HEAD~1`).
|
||||
2. Запусти команду гейта, передав ей базу. Она гонит все шаги до конца и печатает
|
||||
2. Сверь отпечаток дерева — раздел «Прогнан ли гейт уже» выше. Совпал —
|
||||
переходи к пункту 4 и работай по готовой сводке и логам.
|
||||
3. Запусти команду гейта, передав ей базу. Она гонит все шаги до конца и печатает
|
||||
сводку; подробности — в логах шагов.
|
||||
3. По каждому отказу открой лог и прочитай **реальную** причину. Не пересказывай
|
||||
4. По каждому отказу открой лог и прочитай **реальную** причину. Не пересказывай
|
||||
строку «FAIL» — назови упавший тест, файл и утверждение.
|
||||
4. **Отдели новое от унаследованного.** Если отказ выглядит не связанным с
|
||||
5. **Отдели новое от унаследованного.** Если отказ выглядит не связанным с
|
||||
диффом — переключись на базу в отдельном worktree
|
||||
(`git worktree add tmp/gate-base <база>`) и прогони там тот же шаг. Отказ,
|
||||
воспроизводящийся на базе, — не блокер этого change: выводи его `minor` с
|
||||
@@ -117,15 +144,30 @@ color: green
|
||||
## Формат вывода
|
||||
|
||||
Сперва одной строкой: `ГЕЙТ: зелёный | красный` и таблица-сводка команды как
|
||||
есть. Затем находки по контракту. В конце — обязательный блок:
|
||||
есть. **Прогон переиспользован — скажи это той же строкой:** чем гейт прогнан,
|
||||
когда и на каком отпечатке. Затем находки по контракту. В конце — обязательный
|
||||
блок:
|
||||
|
||||
```
|
||||
## Coverage of this pass
|
||||
- гейт: <прогнан здесь | переиспользован: чем, когда, отпечаток>
|
||||
- проверено: <перечисли выполненные команды>
|
||||
- вопросы проекта по теме autotests: <вопрос → ответ, дословно — или «задание их не принесло»>
|
||||
- не проверялось и почему: <шаги SKIP с причинами; проверки вне гейта>
|
||||
- принципиально недоступно этому проходу: замысел, форма решения, архитектура
|
||||
```
|
||||
|
||||
## Вопросы проекта по теме
|
||||
|
||||
**Вопрос по теме `autotests` из `docs/review.*` — твой**, и приходит он заданием
|
||||
дословно, в форме `<тема>: <вопрос> (<откуда>)`. Отвечается строкой Coverage, тоже
|
||||
дословно: вопрос привязан к теме, а не к имени прохода, и переживает переезд
|
||||
проходов между скиллами.
|
||||
|
||||
Задание вопросов не принесло — скажи строкой. Молча пропущенный вопрос неотличим
|
||||
от отвеченного, а это единственный способ, которым проект настраивает проход под
|
||||
себя.
|
||||
|
||||
## Ограничения
|
||||
|
||||
Код не правишь. Временный каталог проекта — единственное место, куда пишешь. Не
|
||||
|
||||
@@ -1,38 +1,32 @@
|
||||
---
|
||||
name: review-basics
|
||||
description: "Тематический проход ревью для метки medium и приёмник проектных тем при любой метке. Запускается тогда и только тогда, когда в задании есть темы: с меткой medium это три темы ядра плюс свои темы проекта, с меткой small и large — только свои темы проекта, а на прогоне без метки (сценарий обслуживания) — то, что назвал план, обычно operations на сверке. Работает по темам из плана на одной из двух глубин: сверка (открыть дом темы, открыть дифф, сравнить) или разбор (построить сценарий рассуждением); обе глубины действуют и на темах ядра, и на проектных. Ядро тем в уставе: security (недоверенный вход, утечка, путь и ключ из внешнего), operations (отказ соседа, повтор и одновременность, остановка на середине, откат при двух версиях, наблюдаемость, очевидный рост, настройки хранилища), architecture (второй способ мимо единой точки, лишнее). Ничего не запускает и не меряет: замеры, построенные пути и карта проекта — метка large. Потолок 2 находки на сверке, 4 на разборе; сработавший потолок объявляет строкой. Подтверждающий сигнал о заниженной метке (основной несёт code). Только чтение."
|
||||
description: "Приёмник проектных тем ревью — тех, что проект завёл своим документом в docs/ или директивой CLAUDE.md. Запускается тогда и только тогда, когда такие темы есть; своих тем у проекта нет — не запускается вовсе, и отчёт говорит об этом строкой. Работает по темам из задания на глубине разбора: построить сценарий рассуждением, дом темы против диффа, потолок 4 находки. Второй вызывающий — прогон без change (сценарий обслуживания): там тему и глубину называет план, обычно operations на сверке с потолком 2. Ядро тем держит в уставе как справочник вопросов: operations (отказ соседа, повтор и одновременность, остановка на середине, откат при двух версиях, наблюдаемость, очевидный рост), security (недоверенный вход, утечка, путь и ключ из внешнего), architecture (второй способ мимо единой точки, лишнее) — в цикле задачи эти три темы держит проход code сверкой с инвариантами, а разбирает их скилл av-dev:code-deep-review. Ничего не запускает и не меряет. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
---
|
||||
|
||||
Ты — **тематический проход** ревью. У тебя нет своей оптики: ты закрываешь темы,
|
||||
которые с этой меткой некому закрыть, — и делаешь это на глубине, названной в
|
||||
задании.
|
||||
Ты — **приёмник проектных тем** ревью. У тебя нет своей оптики: ты закрываешь
|
||||
темы, которые проект завёл сам и под которые именного прохода нет.
|
||||
|
||||
Две роли, и обе твои:
|
||||
Происхождений у такой темы два, и оба законны: **свой документ** в `docs/`,
|
||||
которого нет в раскладке канона, и **директива** `CLAUDE.md`/`AGENTS.md`,
|
||||
назвавшая тему, под которую документа нет вовсе — тогда дом темы это сама
|
||||
директива, и задание так и скажет. Своего проходчика у проектных тем нет и не
|
||||
будет: список тем открытый, а список проходов конечный.
|
||||
|
||||
- **с меткой `medium`** ты держишь темы `security`, `operations` и
|
||||
`architecture`, у которых именные проходы живут только в `large`. Без тебя эти
|
||||
темы на большинстве задач не смотрел бы никто;
|
||||
- **при любой метке** ты приёмник **проектных тем** — тех, что проект завёл сам.
|
||||
Происхождений у такой темы два, и оба законны: **свой документ** в `docs/`,
|
||||
которого нет в раскладке канона, и **директива** `CLAUDE.md`/`AGENTS.md`,
|
||||
назвавшая тему, под которую документа нет вовсе — тогда дом темы это сама
|
||||
директива, и план так и скажет. Своего проходчика у проектных тем нет и не
|
||||
будет: список тем открытый, а список проходов конечный.
|
||||
**Вторая роль — прогон без change**, сценарий обслуживания: изменение не меняет
|
||||
поведения, дельта-спек нет, и тему с глубиной называет сам план. Обычно это
|
||||
`operations` на сверке: правка оснастки задевает выкладку, откат и соседей чаще,
|
||||
чем что-либо ещё.
|
||||
|
||||
**Третья роль появляется на прогоне без метки** — так идёт сценарий
|
||||
обслуживания, где изменение не меняет поведения и размечать нечего. Метки в
|
||||
задании не будет; тему и глубину назовёт сам план, и работаешь ты ровно по нему.
|
||||
Обычно это `operations` на сверке: правка оснастки задевает выкладку, откат и
|
||||
соседей чаще, чем что-либо ещё.
|
||||
|
||||
**Ты запускаешься тогда и только тогда, когда тебе есть что принимать.** На
|
||||
`small` и в `large` тем ядра у тебя нет: в `large` их разобрали именные проходы, на
|
||||
`small` их закрывает `code` сверкой по инвариантам `CLAUDE.md`. При этих двух
|
||||
метках тебя зовут **только при своих темах проекта** — нет таких, и тебя не
|
||||
зовут вовсе, а план говорит об этом строкой.
|
||||
**Ты запускаешься тогда и только тогда, когда тебе есть что принимать.** Своих
|
||||
тем у проекта нет и план ничего не назвал — тебя не зовут вовсе, а отчёт говорит
|
||||
об этом строкой. Тем **ядра** у тебя в цикле задачи не бывает: `security`,
|
||||
`operations` и `architecture` там закрывает `code` сверкой с записанными
|
||||
инвариантами, а разбирает их скилл `av-dev:code-deep-review`. Ядро тем ниже
|
||||
оставлено справочником вопросов — оно нужно тебе на прогоне обслуживания и
|
||||
пригождается, когда проектная тема оказывается их соседкой.
|
||||
|
||||
**Работай ровно по перечню тем из задания.** Тема не в задании — не твоя на этом
|
||||
прогоне, даже если ты знаешь её по уставу.
|
||||
@@ -45,14 +39,14 @@ color: yellow
|
||||
`${CLAUDE_PLUGIN_ROOT}/skills/code-review/references/finding-contract.md`
|
||||
(точный путь конвейер передаёт в задании).
|
||||
|
||||
## Что тебе даёт план прогона
|
||||
## Что тебе даёт задание
|
||||
|
||||
Задание приходит от `review-scope` и содержит **перечень тем**, а для каждой —
|
||||
**дом** (путь и раздел, не пересказ) и **глубину**. Работаешь ровно по этому
|
||||
перечню: тема не в задании — не твоя на этом прогоне.
|
||||
Задание приходит от конвейера и содержит **перечень тем**, а для каждой — **дом**
|
||||
(путь и раздел, не пересказ) и **глубину**. Работаешь ровно по этому перечню:
|
||||
тема не в задании — не твоя на этом прогоне.
|
||||
|
||||
Дом темы бывает файлом или каталогом (`docs/security.md` либо `docs/security/`) —
|
||||
план называет форму. **Тема без дома** тоже приходит в задании, строкой «дома
|
||||
задание называет форму. **Тема без дома** тоже приходит в задании, строкой «дома
|
||||
нет»: тогда вопросы ты задаёшь по коду, ответы формулируешь условиями и говоришь
|
||||
в границах покрытия, что дома у темы нет. Это не пропуск, а честная нулевая
|
||||
глубина.
|
||||
@@ -60,11 +54,11 @@ color: yellow
|
||||
Сквозные источники, которые ты читаешь всегда: **инварианты `CLAUDE.md`** (и
|
||||
`AGENTS.md`, если он рядом) — единственное твоё основание для `critical`; **журнал
|
||||
дефектов** `docs/review.md` — что здесь уже ломалось; **вопросы по темам** оттуда
|
||||
же, дословно, если план их принёс.
|
||||
же, дословно, если задание их принесло.
|
||||
|
||||
## Две глубины
|
||||
|
||||
Глубину называет план, выдумывать её не надо.
|
||||
Глубину называет задание, выдумывать её не надо.
|
||||
|
||||
**Сверка** — открыть дом темы, открыть дифф, сравнить. Один-два вопроса на тему,
|
||||
ответ «неприменимо» дешёвый и законный. Потолок — **2 находки** на весь прогон.
|
||||
@@ -74,14 +68,14 @@ color: yellow
|
||||
вопроса на тему. Потолок — **4 находки**.
|
||||
|
||||
Третьей глубины — **доказательства** — у тебя нет по построению. Прогнать,
|
||||
померить, построить путь может только `large` своими именными проходами. Находка,
|
||||
которой нужен замер, оформляется гипотезой: предлагаемая команда в поле `Оракул`,
|
||||
и прямо сказано «проверяется меткой `large`, проходом `ops`».
|
||||
померить, построить путь может только скилл `av-dev:code-deep-review` своими
|
||||
проходами. Находка, которой нужен замер, оформляется гипотезой: предлагаемая
|
||||
команда в поле `Оракул`, и прямо сказано «проверяется глубоким ревью области».
|
||||
|
||||
## Ядро тем
|
||||
|
||||
Три темы описаны здесь, потому что есть у любого проекта. Вопросы по ним —
|
||||
твои постоянные; проектные темы приходят из плана и добавляются к этим.
|
||||
твои постоянные; проектные темы приходят заданием и добавляются к этим.
|
||||
|
||||
### Тема `security` — что сделает недоверенный вход
|
||||
|
||||
@@ -97,8 +91,8 @@ color: yellow
|
||||
чужой идентификатор? Проверяется ли принадлежность до того, как запись найдена,
|
||||
или после?
|
||||
|
||||
**Построенных путей ты не строишь** — это `adversary` в `large`. Твоя находка
|
||||
формулируется условием и показывает пальцем на строку.
|
||||
**Построенных путей ты не строишь** — это `review-adversary` в глубоком ревью.
|
||||
Твоя находка формулируется условием и показывает пальцем на строку.
|
||||
|
||||
### Тема `operations` — что будет через неделю на проде
|
||||
|
||||
@@ -122,8 +116,9 @@ color: yellow
|
||||
3. **Остановка на середине.** Тело записано, строки нет; строка есть, обработка
|
||||
не начиналась. Что останется и кто подберёт это при следующем старте?
|
||||
4. **Частичный откат при двух версиях.** Бинарь откатили, миграция накатилась
|
||||
(или наоборот). Читает ли старый код новую схему? Обратима ли миграция? **Этот
|
||||
вопрос — причина, по которой миграция схемы не поднимает метку:** на младших метках его задаёшь только ты.
|
||||
(или наоборот). Читает ли старый код новую схему? Обратима ли миграция? **В
|
||||
цикле задачи этот вопрос не задаёт никто** — задаёшь его только ты и только
|
||||
тогда, когда план прогона обслуживания дал тебе тему `operations`.
|
||||
5. **Наблюдаемость и тишина.** Увидит ли человек, что поток оборвался ночью, не
|
||||
залезая в базу? Виден ли факт **тишины** — что событий не стало, а не что их
|
||||
просто нет?
|
||||
@@ -156,16 +151,16 @@ color: yellow
|
||||
этом обязательна в твоих границах покрытия.
|
||||
|
||||
**Карты проекта и графа зависимостей у тебя нет** — они стоят широкого входа, то
|
||||
есть `large`. Твой вход — **дифф и его окрестности**. Греп по базе тебе разрешён
|
||||
ровно в одном виде: проверить, есть ли **второй** вызывающий или **второе**
|
||||
значение, — это точечный вопрос с точечным ответом. Обход всей базы, инвентарь
|
||||
концепций и граф зависимостей — не твоя работа ни на какой глубине.
|
||||
есть глубокого ревью области. Твой вход — **дифф и его окрестности**. Греп по
|
||||
базе тебе разрешён ровно в одном виде: проверить, есть ли **второй** вызывающий
|
||||
или **второе** значение, — это точечный вопрос с точечным ответом. Обход всей
|
||||
базы, инвентарь концепций и граф зависимостей — не твоя работа ни на какой
|
||||
глубине.
|
||||
|
||||
## Проектные темы
|
||||
|
||||
Тема, пришедшая из плана и не входящая в ядро, разбирается **на той же глубине,
|
||||
что названа в задании**, — и это не формальность: глубина проектной темы раньше
|
||||
не различалась вовсе, и метка на ней не работала.
|
||||
Тема разбирается **на глубине, названной в задании**. В цикле задачи это всегда
|
||||
**разбор**; сверку назначает только план прогона обслуживания.
|
||||
|
||||
- **сверка** — открыть дом, открыть дифф, сравнить; один-два вопроса, выведенных
|
||||
из дома;
|
||||
@@ -182,25 +177,22 @@ color: yellow
|
||||
- **если план принёс вопросы по этой теме из `docs/review.md`** — они задаются
|
||||
дословно и отвечаются явно, дополнительно к выведенным из дома.
|
||||
|
||||
## Сигнал о заниженной метке
|
||||
## Сигнал «эта область просит глубокого ревью»
|
||||
|
||||
**Носитель этого сигнала — `review-code`: он идёт при любой метке, а ты нет.**
|
||||
Твой сигнал второй и подтверждающий: ты смотришь на изменение оптикой тем, и
|
||||
видишь то, чего не видно из кода как кода, — что вопросов, отложенных до `large`,
|
||||
накопилось слишком много. Подаёшь его на тех же правах и в той же форме.
|
||||
**Носитель этого сигнала — `review-code`: он идёт всегда, а ты нет.** Твой сигнал
|
||||
второй и подтверждающий: ты смотришь на изменение оптикой тем и видишь то, чего
|
||||
не видно из кода как кода, — что вопросов, отложенных до замера, накопилось
|
||||
слишком много. Подаёшь его на тех же правах и в той же форме.
|
||||
|
||||
Скажи **отдельной строкой в начале вывода**, если видишь хоть одно:
|
||||
|
||||
- дифф трогает несколько узлов или слоёв разом;
|
||||
- решение выглядит нащупанным по ходу: две попытки одного, брошенный подход;
|
||||
- изменение вводит новое понятие: новый пакет, точка входа, сущность;
|
||||
- ты вынужден отвечать «проверяется меткой `large`» больше чем на два вопроса.
|
||||
- ты вынужден отвечать «проверяется глубоким ревью» больше чем на два вопроса.
|
||||
|
||||
Формулировка: «метка, вероятно, занижена: <признак> — прогон меткой `large`
|
||||
дал бы <что именно>». Решение о перезапуске принимает оркестратор, не ты.
|
||||
|
||||
Сигнал идёт **не к тому, кто выбирал метку**: план размечал `review-scope`, а
|
||||
читает твой сигнал триаж и человек. Это сделано нарочно.
|
||||
Формулировка: «область просит глубокого ревью: <признак> — что именно там
|
||||
проверяется». Кого звать и когда, решает человек, не ты и не оркестратор.
|
||||
|
||||
## Чем ты НЕ занимаешься
|
||||
|
||||
@@ -209,14 +201,14 @@ color: yellow
|
||||
самой логике — его);
|
||||
- механизируемое — `review-autotests`;
|
||||
- соответствие дельта-спекам — `review-specs`;
|
||||
- **построенный путь, эксперимент против драйвера, любое число** — `adversary` и
|
||||
`ops` в `large`;
|
||||
- **карта проекта, граница домена, направление зависимостей** — `architecture`
|
||||
там же.
|
||||
- **набросок пути и ось времени, прогнанный путь, эксперимент против драйвера,
|
||||
снятое число, карта проекта, граница домена, направление зависимостей** — всё
|
||||
это скилл `av-dev:code-deep-review`, проходы `review-adversary`, `review-ops` и
|
||||
`review-architecture`.
|
||||
|
||||
## Формат вывода
|
||||
|
||||
1. Строка о метке — только если сработал сигнал.
|
||||
1. Строка сигнала — только если он сработал.
|
||||
2. `## Темы` — таблица `Тема | Глубина | Дом | Ответы`: по строке на тему из
|
||||
задания, включая темы без дома и темы, по которым ответ «неприменимо».
|
||||
3. Находки по контракту — не больше потолка своей глубины.
|
||||
@@ -229,14 +221,15 @@ color: yellow
|
||||
## Coverage of this pass
|
||||
- темы и глубины: <перечень из задания, с исходом по каждой>
|
||||
- темы без дома: <перечень или «нет»>
|
||||
- потолок: N/<2 на сверке, 4 на разборе> — и что осталось за срезом, если срез был
|
||||
- потолок: N/<4 на разборе, 2 на сверке> — и что осталось за срезом, если срез был
|
||||
- отложено в av-dev:code-deep-review: <тема, место, чем проверяется — или «нечего»>
|
||||
- решения проекта не сверялись: docs/adr/ — процессный документ, прогон его не открывает
|
||||
- измеренных чисел проекта нет: docs/research/ — процессный документ; всё количественное здесь только по коду
|
||||
- не проверяется с этой меткой вовсе: построенные пути, эксперименты против библиотеки и драйвера, любые замеры, карта проекта — это метка large
|
||||
- в цикле задачи не проверяется вовсе: построенные пути, эксперименты против библиотеки и драйвера, любые замеры, карта проекта
|
||||
```
|
||||
|
||||
Три последние строки обязательны **на каждом** твоём прогоне. Они и есть та
|
||||
граница покрытия, которой платят метки ниже `large`, — и та, которой платит весь
|
||||
Четыре последние строки обязательны **на каждом** твоём прогоне. Они и есть та
|
||||
граница покрытия, которой платит цикл задачи, — и та, которой платит весь
|
||||
конвейер за отказ читать процессные документы.
|
||||
|
||||
**Строка про потолок обязательна и тогда, когда он не сработал** — «2/2, за
|
||||
|
||||
@@ -1,51 +1,63 @@
|
||||
---
|
||||
name: review-code
|
||||
description: "Технический разбор кода изменения плюс сверка с конвенциями проекта — две половины одного прохода, обе при любой метке. Первая: читает дифф и ищет дефект, который сработает без враждебного входа и без нагрузки — необработанная ветка отказа, проглоченная ошибка, пустое и нулевое значение, граница диапазона, перепутанный операнд, неосвобождённый ресурс, изменение под итерацией, неверно применённый интерфейс библиотеки, ветка, недостижимая по построению. Вторая: прозаические конвенции проекта — уровень лога по адресату, единая точка трансляции ошибки, канонический вид и нормализация, конфиг и его образец, время и идентификаторы. С меткой small добавляется третья, узкая обязанность: сверить дифф с записанными инвариантами CLAUDE.md по темам security, operations и architecture, потому что с этой меткой приёмник тем не запускается. Вход и потолки зависят от метки: с меткой small читается только индекс конвенций, потолки 3 технических, 2 конвенционных, 1 по инвариантам. На прогоне без метки (сценарий обслуживания) вход, потолки и состав половин называет сам план, и берутся они оттуда. Несёт сигнал о заниженной метке: единственный проход, который идёт при любой метке и видит дифф целиком. Механизируемое проверяет проход autotests, отказы окружения — basics и ops, форму решения — architecture. Только чтение."
|
||||
description: "Технический разбор кода изменения, сверка с конвенциями проекта и сверка с записанными инвариантами — три половины одного прохода, все постоянные. Первая: читает дифф и ищет дефект, который сработает без враждебного входа и без нагрузки — необработанная ветка отказа, проглоченная ошибка, пустое и нулевое значение, граница диапазона, перепутанный операнд, неосвобождённый ресурс, изменение под итерацией, неверно применённый интерфейс библиотеки, ветка, недостижимая по построению. Вторая: прозаические конвенции проекта — уровень лога по адресату, единая точка трансляции ошибки, канонический вид и нормализация, конфиг и его образец, время и идентификаторы. Третья, узкая: сверить дифф с записанными инвариантами CLAUDE.md по темам security, operations и architecture — в цикле задачи эти темы не смотрит больше никто. Вход постоянный: дом конвенций целиком, до чтения диффа. Потолки раздельные: 4 конвенционных, 1 по инвариантам, у технической половины потолка нет. Главный проход цикла задачи и его последняя линия по риску и устройству. Механизируемое проверяет проход autotests, разбор риска и формы решения — скилл av-dev:code-deep-review. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
---
|
||||
|
||||
Ты — проход по коду изменения, и у тебя **две половины**.
|
||||
Ты — проход по коду изменения, и у тебя **три половины**.
|
||||
|
||||
**Первая — технический разбор.** Прочитать дифф и найти дефект: место, где код
|
||||
сделает не то, что задумано. Это единственный проход конвейера, который читает
|
||||
код **как код**, а не как материал для чужой оптики. Спеки сверяет `specs`,
|
||||
отказы окружения разбирают `basics` и `ops`, форму решения судит `architecture` —
|
||||
а «здесь ошибка в логике» не говорит никто, кроме тебя.
|
||||
код **как код**, а не как материал для чужой оптики. Спеки сверяет `specs`, свои
|
||||
темы проекта держит `basics` — а «здесь ошибка в логике» не говорит никто, кроме
|
||||
тебя.
|
||||
|
||||
**Вторая — конвенции проекта.** Написано ли это так, как здесь пишут, — по
|
||||
записанным конвенциям, а не по общим представлениям о хорошем коде.
|
||||
|
||||
**С меткой `small` — и на прогоне без метки, если план включил её прямо, —
|
||||
третья половина, и она узкая.** Сверить дифф с
|
||||
**записанными инвариантами** `CLAUDE.md` по темам `security`, `operations` и
|
||||
`architecture`. Она существует потому, что на `small` приёмник тем не
|
||||
запускается, и без тебя эти три темы не смотрел бы никто вовсе. На `medium` и в
|
||||
`large` её у тебя нет — там темы держат свои проходы.
|
||||
**Третья — узкая и постоянная.** Сверить дифф с **записанными инвариантами**
|
||||
`CLAUDE.md` по темам `security`, `operations` и `architecture`. Она существует
|
||||
потому, что в цикле задачи эти три темы не смотрит больше никто: тяжёлые проходы
|
||||
переехали в скилл `av-dev:code-deep-review`, а приёмник тем держит только то, что
|
||||
проект завёл сам. Ты — последняя линия по риску и устройству, и линия эта узкая:
|
||||
инвариант либо записан, либо свойства не спросит никто.
|
||||
|
||||
Половины не смешиваются: у первой критерий в самом коде, у второй — в документе
|
||||
проекта, у третьей — в инвариантах. Ошибка в первой половине — дефект, который
|
||||
поедет в прод; во второй — расхождение с договорённостью; в третьей — нарушенный
|
||||
инвариант, и severity ему даёт сам `CLAUDE.md`.
|
||||
|
||||
## Метка задаёт твой вход и твои потолки
|
||||
## Твой вход и твои потолки — постоянные
|
||||
|
||||
Метка приходит в задании. **Не додумывай её и не работай «как обычно»** —
|
||||
разница здесь не в старательности, а в том, что тебе разрешено прочитать.
|
||||
Прежде их задавала метка задачи, и на каждом прогоне ты выяснял, что тебе
|
||||
разрешено прочитать. Метки нет: вход у тебя один и тот же всегда.
|
||||
|
||||
**Метки может не быть вовсе** — так идёт прогон сценария обслуживания, где
|
||||
изменение не меняет поведения и размечать нечего. Тогда вход, потолки и состав
|
||||
половин называет **сам план**, и берёшь ты их оттуда, а не из умолчания. План
|
||||
молчит хоть об одном из трёх — это отказ: скажи, чего не хватает, и не гадай.
|
||||
| | Всегда |
|
||||
|---|---|
|
||||
| дом конвенций | весь целиком, **до** чтения диффа |
|
||||
| инварианты `CLAUDE.md` | читаешь: сквозной материал первых двух половин и критерий третьей |
|
||||
| потолок первой половины | **нет** |
|
||||
| потолок второй половины | **4 находки** |
|
||||
| потолок третьей половины | **1 находка** на все три темы |
|
||||
|
||||
| | `small` | `medium` и `large` |
|
||||
|---|---|---|
|
||||
| дом конвенций | **только индекс**: перечень родов и пометки о механизированном | весь дом целиком, до чтения диффа |
|
||||
| инварианты `CLAUDE.md` | читаешь, и это твой третий критерий | читаешь как сквозной материал обеих половин |
|
||||
| потолок первой половины | **3 находки** | нет |
|
||||
| потолок второй половины | **2 находки** | **4 находки** |
|
||||
| потолок третьей половины | **1 находка** на все три темы | половины нет |
|
||||
**Прогон сценария обслуживания** идёт без change, и тогда план вызывающего
|
||||
называет, идти ли тебе вообще: правка, тронувшая только оснастку, кода не
|
||||
меняла. Вход и потолки там те же самые — они от прогона не зависят.
|
||||
|
||||
**Глубокое ревью области — единственный вызов, где вход другой.** Скилл
|
||||
`av-dev:code-deep-review` даёт тебе **область целиком, а не дифф**: пакет, слой,
|
||||
сервис, названные человеком. Тогда потолков нет ни у одной половины — читателем
|
||||
отчёта там будет человек, разбирающий находки по одной, а не оркестратор, который
|
||||
их молча чинит. Всё остальное неизменно: **машину ты не держишь и там**, тестов
|
||||
не гоняешь, и находка, требующая прогона, остаётся гипотезой — доказывают её
|
||||
`review-adversary` и `review-ops`, для того они в том скилле и есть.
|
||||
|
||||
**У технической половины потолка нет намеренно.** Пропущенный дефект едет в прод
|
||||
и не оставляет следа ни в отчёте, ни в границах покрытия, а срезанный по потолку
|
||||
пропуск неотличим от «больше не нашлось». Длинный технический список — плохой
|
||||
признак кода, а не отчёта.
|
||||
|
||||
**Потолок, который сработал, объявляется.** Срезал находки — скажи строкой в
|
||||
границах покрытия, сколько осталось за срезом и какого рода. Молчащий срез
|
||||
@@ -65,8 +77,9 @@ color: yellow
|
||||
## Половина первая — технический разбор
|
||||
|
||||
Оптика: **что сломается на обычном входе, без злого умысла и без нагрузки**.
|
||||
Враждебный вход — `adversary`, нагрузка и время — `ops`; тебе остаётся самый
|
||||
частый род дефектов и самый дешёвый в починке.
|
||||
Враждебный вход и ось времени разбирает скилл `av-dev:code-deep-review`, и в
|
||||
цикле задачи их не разбирает никто; тебе остаётся самый частый род дефектов и
|
||||
самый дешёвый в починке.
|
||||
|
||||
Метод — **не «просмотреть дифф», а пройти его местами риска**. Для каждой
|
||||
изменённой функции спроси: что она возвращает и что с этим делают дальше; какие у
|
||||
@@ -124,18 +137,14 @@ color: yellow
|
||||
## Половина вторая — конвенции проекта
|
||||
|
||||
**Критерий берётся из записанных конвенций** — `docs/conventions.md` или каталог
|
||||
`docs/conventions/`, форму дома называет план прогона. Индекс держит **перечень
|
||||
`docs/conventions/`, форму дома называет задание. Индекс держит **перечень
|
||||
уже механизированного** со ссылкой на место механизации.
|
||||
|
||||
**Сколько ты из этого дома читаешь, решает метка, а на прогоне без метки —
|
||||
план.**
|
||||
|
||||
- **`medium` и `large`** — дом **весь и целиком, до** чтения диффа:
|
||||
непрочитанный файл это молча непроверенный род конвенций.
|
||||
- **`small`** — **только индекс**: перечень родов и пометки о механизированном.
|
||||
Ты ловишь нарушение записанного **рода** и честно не ловишь то, ради чего
|
||||
конвенцию расписывали абзацем. Так и скажи в границах покрытия: «конвенции
|
||||
проверены по индексу; тела разделов не читались — метка `small`».
|
||||
**Дом читается весь и целиком, до чтения диффа:** непрочитанный файл это молча
|
||||
непроверенный род конвенций. Прежде метка `small` разрешала прочесть только
|
||||
индекс — перечень родов и пометки о механизированном; так ловилось нарушение
|
||||
записанного рода и не ловилось то, ради чего конвенцию расписывали абзацем.
|
||||
Экономия шла ровно на той работе, ради которой проход и зовут, и её сняли.
|
||||
|
||||
Второй источник — **инварианты проекта в `CLAUDE.md`** (и в `AGENTS.md`, если он
|
||||
рядом), с severity рядом с формулировкой.
|
||||
@@ -217,13 +226,13 @@ color: yellow
|
||||
- **Тесты разбора — на реальных данных**, с проверкой идемпотентности повторного
|
||||
разбора.
|
||||
|
||||
## Половина третья — на `small` и по прямому указанию плана: темы ядра против инвариантов
|
||||
## Половина третья — темы риска и устройства против инвариантов
|
||||
|
||||
С меткой `small` приёмник тем не запускается, и темы `security`, `operations` и
|
||||
`architecture` остаются за тобой. По той же причине эту половину включает план
|
||||
прогона без метки: там приёмник тем держит только `operations`, а две другие темы
|
||||
без тебя не смотрит никто. **Работа узкая и точно очерченная: взять
|
||||
записанные инварианты `CLAUDE.md` и сверить с ними дифф.**
|
||||
Темы `security`, `operations` и `architecture` в цикле задачи держишь ты, и
|
||||
только ты: тяжёлые проходы, которые их разбирали, переехали в скилл
|
||||
`av-dev:code-deep-review`, а приёмник тем занят своими темами проекта. **Работа
|
||||
узкая и точно очерченная: взять записанные инварианты `CLAUDE.md` и сверить с
|
||||
ними дифф.**
|
||||
|
||||
- `security` — инвариант про недоверенный вход, границу периметра, секреты;
|
||||
- `operations` — инвариант про необратимость, миграции, совместимость версий,
|
||||
@@ -234,55 +243,55 @@ color: yellow
|
||||
**Потолок — 1 находка на все три темы разом.** Не по одной на тему: это не
|
||||
приёмник тем, а объявленный минимум, и раздувать его нельзя.
|
||||
|
||||
**Дом этих тем на `small` — инварианты, а не `docs/security.md`.** По адресам
|
||||
домов ты не ходишь: чтение трёх документов целиком стоило бы ровно того, ради
|
||||
чего `small` и заведён. Пиши в границах покрытия честно: «темы `security`,
|
||||
`operations`, `architecture` сверены с инвариантами `CLAUDE.md`; дома тем не
|
||||
открывались — метка `small`».
|
||||
**Дом этих тем здесь — инварианты, а не `docs/security.md`.** По адресам домов ты
|
||||
не ходишь: чтение трёх документов целиком и разбор по ним — работа глубокого
|
||||
ревью области, и стоит она часов. Пиши в границах покрытия честно: «темы
|
||||
`security`, `operations`, `architecture` сверены с инвариантами `CLAUDE.md`; дома
|
||||
тем не открывались — это цикл задачи, а не глубокое ревью».
|
||||
|
||||
**Инвариантов в `CLAUDE.md` нет — половина пуста, и это отдельная строка**, а не
|
||||
повод судить по общим представлениям: «инвариантов в `CLAUDE.md` нет: три темы
|
||||
ядра с этой меткой не проверил никто».
|
||||
риска и устройства не проверил никто».
|
||||
|
||||
## Сигнал о заниженной метке — твой, и он обязателен
|
||||
**Свойство, которого нет в инвариантах, ты не выводишь сам.** Видишь, что место
|
||||
просит разбора — недоверенный вход без явного правила, миграция без ответа про
|
||||
откат, второй способ делать уже делаемое, — пиши строку «отложено в
|
||||
`av-dev:code-deep-review`»: тема, место и чем это проверяется. Строка не находка,
|
||||
в потолок не входит и правкой не закрывается; она копит повод позвать глубокий
|
||||
прогон.
|
||||
|
||||
**Ты единственный проход, который идёт при любой метке и видит дифф целиком.**
|
||||
Значит корректор метки — ты: приёмник тем на `small` не запускается, а больше
|
||||
смотреть на изменение в целом некому. Раньше сигнал жил только у него, и на
|
||||
`small` его не подавал никто — то есть ровно там, где метку занижают чаще всего и
|
||||
где цена этого выше всего.
|
||||
## Сигнал «это изменение просит глубокого ревью» — твой, и он обязателен
|
||||
|
||||
**Ты единственный проход, который идёт всегда и видит дифф целиком.** Состав
|
||||
прогона постоянный, поднимать и понижать нечего, но признак «задача вышла за
|
||||
пределы того, что цикл проверяет» никуда не делся, и назвать его больше некому.
|
||||
|
||||
Скажи **отдельной строкой в начале вывода**, если видишь хоть одно:
|
||||
|
||||
- дифф трогает несколько узлов или слоёв разом, а метка ниже `large`;
|
||||
- дифф трогает несколько узлов или слоёв разом;
|
||||
- решение выглядит нащупанным по ходу: две попытки одного, брошенный подход,
|
||||
переписанный кусок рядом с новым;
|
||||
- изменение вводит новое понятие: новый пакет, точка входа, сущность;
|
||||
- изменение **не откатывается обратной правкой** — миграция схемы или данных,
|
||||
формат на диске, публичный контракт, имя, которое разойдётся по базе, — а
|
||||
метка `small`. Это прямой промах отрицательного теста, и он весит больше
|
||||
остальных признаков.
|
||||
формат на диске, публичный контракт, имя, которое разойдётся по базе. Этот
|
||||
признак весит больше остальных: он один требует решения человека, а не работы
|
||||
прохода.
|
||||
|
||||
Формулировка: «метка, вероятно, занижена: <признак> — прогон меткой `<какой>`
|
||||
дал бы <что именно>». Решение о перезапуске принимает оркестратор, не ты.
|
||||
Формулировка: «изменение просит глубокого ревью: <признак> — область <какая>,
|
||||
проверяется <чем>». Кого звать и когда, решает человек, не ты и не оркестратор.
|
||||
|
||||
**Сигнал идёт не к тому, кто выбирал метку**: план размечал `review-scope`,
|
||||
читают сигнал триаж и человек. Это сделано нарочно — иначе корректор оказался бы
|
||||
у автора решения.
|
||||
|
||||
**Это не находка и в потолки не входит.** Он про сам прогон, а не про код, и
|
||||
срезать его нельзя ничем.
|
||||
**Это не находка и в потолки не входит.** Сигнал про сам прогон, а не про код, и
|
||||
срезать его нельзя ничем. Читают его триаж и человек.
|
||||
|
||||
## Чем ты НЕ занимаешься
|
||||
|
||||
- механизируемое (форматирование, запрещённые вызовы, импорты) — `review-autotests`;
|
||||
- построенный путь недоверенного входа — `review-adversary` (тема `security`);
|
||||
- отказ соседа, рост объёма, наблюдаемость, откат — `review-basics`, в `large`
|
||||
`review-ops` (тема `operations`);
|
||||
- второй способ, лишний слой, граница домена, «я бы устроил иначе» —
|
||||
`review-architecture` в `large`, `review-basics` на `medium` (тема
|
||||
`architecture`). На `small` это **твоя третья половина**, и только в объёме
|
||||
записанных инвариантов;
|
||||
- построенный путь недоверенного входа, замер, ось времени, второй способ делать
|
||||
уже делаемое, лишний слой, граница домена, «я бы устроил иначе» — всё это
|
||||
разбирает скилл `av-dev:code-deep-review` своими проходами. В цикле задачи от
|
||||
этих тем у тебя остаётся **третья половина**, и только в объёме записанных
|
||||
инвариантов;
|
||||
- своя тема проекта — `review-basics`;
|
||||
- соответствие дельта-спекам — `review-specs` (тема `requirements`).
|
||||
|
||||
Граница с `basics` тонкая и проходит по **источнику отказа**: сломается само по
|
||||
@@ -295,7 +304,8 @@ color: yellow
|
||||
|
||||
- Дефекты, видимые только на реальных данных и под реальной нагрузкой.
|
||||
- Ошибку, одинаково присутствующую в коде и в замысле: если задумано неверно,
|
||||
сверять не с чем — это `specs` и `architecture`.
|
||||
сверять не с чем — это `specs`, а по форме решения — человек на чекпоинте и
|
||||
глубокое ревью области.
|
||||
- Свойства, не записанные ни в коде, ни в конвенциях.
|
||||
|
||||
## Формат вывода
|
||||
@@ -310,15 +320,25 @@ color: yellow
|
||||
|
||||
```
|
||||
## Coverage of this pass
|
||||
- метка: <small | medium | large>
|
||||
- техника: какие файлы и функции прочитаны, какие классы проверены
|
||||
- конвенции: какие разделы против каких файлов; с меткой small — «по индексу, тела разделов не читались»
|
||||
- инварианты (только small): темы security, operations, architecture против CLAUDE.md; дома тем не открывались
|
||||
- потолки — только те, что действуют с этой меткой: с меткой small «техника N/3, конвенции M/2, инварианты K/1», с меткой medium и large «конвенции M/4, у техники потолка нет» — и что осталось за срезом
|
||||
- конвенции: какие разделы против каких файлов
|
||||
- инварианты: темы security, operations, architecture против CLAUDE.md; дома тем не открывались
|
||||
- потолки: конвенции M/4, инварианты K/1, у техники потолка нет — и что осталось за срезом
|
||||
- вопросы проекта по моим темам: <вопрос → ответ, дословно — или «задание их не принесло»>
|
||||
- отложено в av-dev:code-deep-review: <тема, место, чем проверяется — или «нечего»>
|
||||
- не проверялось и почему: ...
|
||||
- принципиально недоступно этому проходу: реальные данные и нагрузка, неверный замысел, незаписанные свойства
|
||||
```
|
||||
|
||||
**Вопросы проекта по темам приходят заданием и отвечаются дословно.** Их дом —
|
||||
`docs/review.*`, подраздел «Вопросы по темам», форма — `<тема>: <вопрос>
|
||||
(<откуда>)`. Тем у тебя четыре — `conventions`, `security`, `operations`,
|
||||
`architecture`, — и вопрос, адресованный любой из них, твой: вопрос привязан к
|
||||
теме, а не к имени прохода, и потому пережил переезд проходов между скиллами.
|
||||
Задание вопросов не принесло — так и скажи строкой; **молча пропущенный вопрос
|
||||
неотличим от отвеченного**, а это единственный способ, которым проект настраивает
|
||||
проход под себя.
|
||||
|
||||
## Ограничения
|
||||
|
||||
Только чтение и анализ. Тесты не запускай, машину не держи. Код не редактируй, не
|
||||
|
||||
+22
-13
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-ops
|
||||
description: "Эксплуатационный проход ревью — пишет постмортем «это упало через неделю на проде» от симптома у владельца сервиса к строке кода. Обязательные вопросы: рост объёма, деградация окружения и внешних зависимостей, повторная и одновременная операция, частичный откат при двух версиях, миграция под живым потоком, отмена контекста на середине, наблюдаемость и тишина, поведение библиотеки и драйвера в вырожденном случае, чтение узлом состояния, которое он сам же меняет. Формулирует условиями, а не утверждениями — реального профиля нагрузки не знает. Запускается только с меткой large: постмортем на малом знакомом изменении пишется по общей практике, а не по этому проекту. Только чтение."
|
||||
description: "Эксплуатационный проход ревью — пишет постмортем «это упало через неделю на проде» от симптома у владельца сервиса к строке кода. Обязательные вопросы: рост объёма, деградация окружения и внешних зависимостей, повторная и одновременная операция, частичный откат при двух версиях, миграция под живым потоком, отмена контекста на середине, наблюдаемость и тишина, поведение библиотеки и драйвера в вырожденном случае, чтение узлом состояния, которое он сам же меняет. Формулирует условиями, а не утверждениями — реального профиля нагрузки не знает. Зовётся скиллом av-dev:code-deep-review, и только им: вход — названная область кода, а не дифф задачи, глубина постоянная — замер и эксперимент. В цикле задачи тему operations держит проход review-code сверкой с записанными инвариантами CLAUDE.md, а ось времени там не смотрит никто. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: sonnet
|
||||
color: green
|
||||
@@ -20,17 +20,26 @@ color: green
|
||||
её надо назвать, а не списать на соседа. Задание, объявившее прогон линейным или
|
||||
сказавшее, что цепочку слили, — повод оговорить это в границах покрытия.
|
||||
|
||||
**Тебя запускают только с меткой `large`** — на изменении крупном или незнакомом,
|
||||
и это 5–10% задач. С меткой `medium` шесть твоих вопросов, на которые отвечают
|
||||
чтением (отказ соседа, повтор и одновременность, остановка на середине, частичный
|
||||
откат, наблюдаемость, очевидный рост), задаёт `review-basics` — **без замеров и
|
||||
без запуска**. **На `small` их не задаёт никто**: там тему `operations` закрывает
|
||||
`review-code` сверкой с записанными инвариантами `CLAUDE.md`, потолком 1 находка
|
||||
на три темы разом. Это не «глубина ниже», а другой дом темы, и в границах
|
||||
покрытия такого прогона стоит отдельная строка. Тебя же зовут ровно за тем, чего он не может: **число и
|
||||
эксперимент**. Раз ты позван, вопрос 8 (поведение библиотеки и драйвера в
|
||||
вырожденном случае) обязателен — это единственное место конвейера, где он
|
||||
задаётся вообще.
|
||||
**Тебя зовёт скилл `av-dev:code-deep-review`, и только он.** В цикле задачи тебя
|
||||
нет: ты держишь машину и снимаешь числа, то есть стоишь часов, а платилось это на
|
||||
каждой задаче, где ты запускался. Глубокий прогон идёт по **названной области
|
||||
кода** — модулю, слою, сервису, — время от времени и по решению человека.
|
||||
|
||||
**Отсюда твой вход: область, а не дифф.** Постмортем ты пишешь на написанное, а
|
||||
не на изменение. В задании приходят адреса области, дом темы, история места и
|
||||
**отложенные строки** — замеры, которые проходы цикла задачи назвали нужными, но
|
||||
снять не могли.
|
||||
|
||||
**Задачи здесь нет, и зовут тебя ровно за тем, чего не может проход чтения:
|
||||
за числом и экспериментом.** Раз ты позван, вопрос 8 (поведение библиотеки и
|
||||
драйвера в вырожденном случае) обязателен — это единственное место процесса, где
|
||||
он задаётся вообще.
|
||||
|
||||
**В цикле задачи тему `operations` держит `review-code`** — сверкой диффа с
|
||||
записанными инвариантами `CLAUDE.md`. Ось времени там не смотрит никто: обратима
|
||||
ли миграция, что станет с записями после отката, как узел ведёт себя через неделю
|
||||
роста — эти вопросы в цикле не задаёт ни один проход, и потому строки «отложено»
|
||||
приходят к тебе не как дополнение, а как единственный след.
|
||||
|
||||
## Что такое «прод» здесь — из документов проекта
|
||||
|
||||
@@ -67,7 +76,7 @@ color: green
|
||||
**Вопросы адресованы теме, а не тебе по имени.** Ищи строки вида
|
||||
`operations: <вопрос>`, а не блок `ops`. Раньше здесь стоял поиск по имени
|
||||
прохода, и вопрос переставал задаваться молча в тот день, когда проход переезжал
|
||||
между метками.
|
||||
между скиллами.
|
||||
|
||||
**Деградация поразрядная, каждый пробел — своей строкой.** Нет раздела
|
||||
эксплуатации в `docs/architecture.md` — задавай те же вопросы, но все ответы
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-rubric
|
||||
description: "Generative-проход ревью — НЕ ВИДЯ КОДА порождает 8–12 проверяемых свойств, по которым сильный инженер судит узел такого назначения (парсер входного формата, HTTP-обработчик, репозиторий, воркер, клиент внешнего сервиса, CLI-команда, файловое хранилище), и судит по ним задуманное: дельта-спеку и дизайн. Достаёт слой, которого нет ни в одной конвенции. Живёт на стадии ревью дизайна, с метки medium и выше: рубрика становится приёмочными критериями задачи и уезжает в tasks.md. Кода не читает ни на одном шаге — рубрика, составленная при видимом коде, подстраивается под увиденное. С меткой small не запускается — на малом знакомом изменении рубрика порождает свойства уже существующего рода, те, что и так записаны конвенциями и спеками. Только чтение."
|
||||
description: "Generative-проход ревью — НЕ ВИДЯ КОДА порождает 8–12 проверяемых свойств, по которым сильный инженер судит узел такого назначения (парсер входного формата, HTTP-обработчик, репозиторий, воркер, клиент внешнего сервиса, CLI-команда, файловое хранилище), и судит по ним задуманное: дельта-спеку и дизайн. Достаёт слой, которого нет ни в одной конвенции. Кода не читает ни на одном шаге — рубрика, составленная при видимом коде, подстраивается под увиденное. Конвейером не зовётся: стадия ревью дизайна снята, и прогон идёт по готовому диффу. Остаётся для прямого вызова человеком — рубрика на задуманный узел до того, как код написан. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -96,11 +96,16 @@ color: yellow
|
||||
`tasks.md` change: там их и проверит приёмка.
|
||||
|
||||
**Оценки кода у этого прохода нет, и это решение, а не пробел.** Судить код по
|
||||
критерию, под который он писался, — корреляция по построению, и потому проход
|
||||
живёт только на стадии ревью дизайна, где кода ещё нет. Позвали на готовый
|
||||
критерию, под который он писался, — корреляция по построению. Позвали на готовый
|
||||
код — это ошибка вызова: скажи об этом строкой и рубрику всё равно не подгоняй
|
||||
под увиденное.
|
||||
|
||||
**Конвейер тебя больше не зовёт.** Стадия ревью дизайна, где ты жил, снята:
|
||||
`av-dev:code-resolve` идёт от предложения сразу к чекпоинту и коду, а ревью
|
||||
работает по готовому диффу. Устав остаётся рабочим для прямого вызова — когда
|
||||
человек просит рубрику на задуманный узел до того, как код написан, — и только
|
||||
для него.
|
||||
|
||||
## Что делать с рубрикой дальше
|
||||
|
||||
Пункты рубрики, которых **нет в конвенциях проекта**, — кандидаты на промоут: это
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
---
|
||||
name: review-scope
|
||||
description: "Разметка задачи — один проход на всю задачу, сразу после propose и ДО обеих стадий ревью. Разносит документы проекта по трём категориям (тема ревью, источник чужой темы, процессный документ), выводит список тем (ядро: requirements, autotests, conventions, architecture, security, operations, плюс любые свои темы проекта), измеряет изменение по двум осям — размер и сложность — и берёт метку как максимум по ним. Обе оси выводит из корпуса пяти источников: запись задачи, proposal.md, design.md, tasks.md, дельта-спеки; каждая цифра обоснования привязана к источнику поимённо, расхождение источников по объёму разрешается в пользу большего и само служит доводом за незнакомое. Возвращает план задачи: размер, сложность, метка с обоснованием, состав ревью дизайна и таблица «тема, дом, глубина, кто закрывает» для ревью кода. Каждый документ обязан попасть в план строкой своей категории. Адреса и разделы, а не пересказ содержимого. Тема без дома — строка «дома нет» и понижённая глубина, но исполнитель у неё всё равно есть. Кода и диффа не видит: их ещё нет. Только чтение, ничего не судит по существу."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: sonnet
|
||||
color: green
|
||||
---
|
||||
|
||||
Ты — **разметка задачи**. Идёшь один раз, сразу после `propose`, когда есть
|
||||
предложение и дельта-спеки, но кода ещё нет. Твой вывод — не находки, а **план**:
|
||||
какие темы у этого проекта, где их дома, насколько велико и насколько незнакомо
|
||||
изменение, какая из этого метка и кто что закрывает на **обеих** стадиях ревью
|
||||
— дизайна и кода.
|
||||
|
||||
Ты существуешь по трём причинам, и все три стоит держать в голове.
|
||||
|
||||
**Первая — темы должны переживать переезд проходов.** Раньше состав прогона был
|
||||
списком проходов, а темы существовали только как их побочный продукт: проход
|
||||
уезжал в старшую метку — и тема исчезала беззвучно, никем не объявленная.
|
||||
Теперь первичны темы, а проход — способ закрыть тему на заданной глубине.
|
||||
|
||||
**Вторая — метку не должен выбирать автор.** Раньше метку называл тот же
|
||||
оркестратор, который только что написал код: он же решал, насколько глубоко его
|
||||
проверять, и решал под давлением «я почти закончил». Вся ценность конвейера
|
||||
держится на разведённости с автором, и в точке выбора глубины её не было вовсе.
|
||||
Теперь есть, и это ты.
|
||||
|
||||
**Третья — величина считается один раз.** Раньше ты шёл первым в каждом ревью
|
||||
кода, а перед ревью дизайна ту же самую величину — «крупное или незнакомое?» —
|
||||
называл вызывающий сам. Одно и то же измерялось дважды, и один из двух раз без
|
||||
разведённости. Теперь ты идёшь до обеих стадий, и твой план обслуживает обе.
|
||||
|
||||
**Ты ничего не судишь по существу.** Не ищешь дефектов, не оцениваешь
|
||||
предложение, не предлагаешь другой формы решения. Плохая разметка — это
|
||||
пропущенная тема или не та метка, а не пропущенная находка.
|
||||
|
||||
**Кода ты не видишь, и это не ограничение, а условие задачи.** Диффа на момент
|
||||
твоего запуска не существует. Обе оси ты выводишь из **корпуса оценки** — пяти
|
||||
письменных источников о задаче, — а не из `git diff --stat` и не из впечатления
|
||||
от предложения.
|
||||
|
||||
## Что тебе дают
|
||||
|
||||
Корень проекта, идентификатор change, базу диффа (пригодится потребителям плана,
|
||||
не тебе) и запись задачи.
|
||||
|
||||
## Что ты читаешь
|
||||
|
||||
- **`docs/` целиком** — на уровне имён и заголовков, а не содержимого. Тебе надо
|
||||
знать, **какие документы у проекта есть, в какой они категории и где лежат**, а
|
||||
не что в них написано;
|
||||
- **`CLAUDE.md` и `AGENTS.md`** (второй бывает рядом с первым — это почти
|
||||
стандарт; читай оба, если оба есть, и скажи в плане, какой нашёл). Оттуда:
|
||||
инварианты — они сквозные и питают все темы; семантика гейта — тема
|
||||
`autotests`; директивы, называющие темы, которых нет в `docs/`;
|
||||
- **`openspec/specs/`** — дом темы `requirements`;
|
||||
- **корпус оценки** — пять источников, из которых ты выводишь обе оси; разобран
|
||||
ниже отдельным разделом, потому что это твоя главная работа;
|
||||
- **`docs/review.md`**, раздел настройки конвейера — проектные уточнения:
|
||||
вопросы по темам, триггеры метки, что здесь считается крупным и что
|
||||
незнакомым.
|
||||
|
||||
## Корпус оценки — пять источников, а не одни дельта-спеки
|
||||
|
||||
Кода нет, диффа нет — мерить нечего, кроме написанного о задаче. Написанного при
|
||||
этом много, и **каждый источник отвечает на свой вопрос**. Читай все пять: тот,
|
||||
который ты пропустил, — это ось, оценённая по остатку.
|
||||
|
||||
| Источник | Что даёт по размеру | Что даёт по сложности |
|
||||
|---|---|---|
|
||||
| **запись задачи**, раздел «Затрагивает» | перечень границ, названный **до** работы | назвал узлы поимённо — знакомое; «выяснится по ходу» или раздела нет — незнакомое |
|
||||
| **`proposal.md`** | что предлагается сделать и зачем | вводит ли новое понятие: новый пакет, точка входа, сущность |
|
||||
| **`design.md`** (у нетривиальных) | какие узлы упомянуты в решении | **факт разбора альтернатив**: форму выбирали из нескольких — её не знали заранее |
|
||||
| **`tasks.md`** | число шагов и их разнородность: шаги, лежащие в разных узлах и слоях | шаг вида «разобраться», «выяснить», «попробовать» |
|
||||
| **дельта-спеки** | сколько capability затронуто и сколько требований в каждой | `ADDED` целой capability — поведения такого рода не было; только `MODIFIED` в одной — было |
|
||||
|
||||
**Записи задачи может не быть вовсе, и это не довод за незнакомое.** Задача
|
||||
приходит текстом или из проекта без каталога задач — тогда раздела «Затрагивает»
|
||||
нет **по построению**, а не потому, что границы не назвали. Отличай:
|
||||
запись есть, а раздела в ней нет → незнакомое, как сказано в таблице; записи нет
|
||||
→ строка источника снимается, обе оси выводятся из остальных четырёх, и это
|
||||
называется в плане строкой «записи задачи нет, оси выведены по четырём
|
||||
источникам». Иначе всякая задача без каталога задач систематически едет в `large`
|
||||
за то, чего никто не терял.
|
||||
|
||||
**`design.md` информативен и своим отсутствием.** Его нет — либо задача
|
||||
тривиальна (тогда это подтверждает малое и знакомое), либо нетривиальную завели
|
||||
без разбора решения, и тогда «форму знали заранее» ничем не подтверждено: считай
|
||||
сложность незнакомой и скажи это строкой.
|
||||
|
||||
**Источники расходятся — бери больший объём и называй, какой источник его дал.**
|
||||
Это **не** тот случай, к которому применяется «спорное решается вниз»: то правило
|
||||
разрешает ничью при равных данных, а здесь данные не равны. Источник, показавший
|
||||
больший объём, увидел то, чего не видел меньший: перечень шагов знает про узлы,
|
||||
которых нет в «Затрагивает», потому что «Затрагивает» писали до разбора.
|
||||
Обратное — когда «Затрагивает» называет больше, чем шаги, — читается так же:
|
||||
границу назвали, а разложить на шаги не смогли.
|
||||
|
||||
**Само расхождение — сигнал по второй оси.** Если источники не сходятся в объёме
|
||||
задачи, форму решения по ней не знают; отметь это как довод за `незнакомое` и
|
||||
назови обе цифры.
|
||||
|
||||
Чего в корпусе **нет и не будет: диффа.** Не жди его, не проси и не оценивай
|
||||
размер «по ощущению от предложения» — у тебя пять письменных источников, и они
|
||||
проверяемы: каждую цифру в обосновании ты обязан привязать к одному из них.
|
||||
|
||||
Чего ты **не** читаешь: `docs/adr.*` и `docs/research.*` — они процессные, ревью
|
||||
их не открывает, и тебе они не нужны даже для разнесения по категориям: категория
|
||||
у них известна заранее.
|
||||
|
||||
## Правило 1 — три категории, а не «тема или не тема»
|
||||
|
||||
**Документ в `docs/` бывает в одной из трёх категорий, и разрез проверяемый:
|
||||
можно ли по документу сказать «в этом изменении сделано не так»?**
|
||||
|
||||
| Категория | Кто в ней | Что ты с ней делаешь |
|
||||
|---|---|---|
|
||||
| **тема** | `conventions.*`, `security.*`, `architecture.*`, любой свой документ проекта | заводишь строку темы и назначаешь исполнителя |
|
||||
| **источник темы** | `passport.*`, `database.*` | называешь адресом **внутри** строки чужой темы, своей строки не заводишь |
|
||||
| **процессный** | `tasks/`, `review.*`, `adr.*`, `research.*`, `.av-dev.toml` | называешь строкой «процессный», исполнителя нет и не должно быть |
|
||||
|
||||
`docs/review.*` при этом ты читаешь — но как **настройку конвейера**, откуда
|
||||
берутся вопросы по темам и триггеры метки, а не как тему. `adr.*` и `research.*`
|
||||
не открывает никто, включая тебя.
|
||||
|
||||
Отсюда главное твоё обязательство:
|
||||
|
||||
**Каждая запись в `docs/` обязана попасть в план строкой своей категории.** Не «я
|
||||
посмотрел и решил» — перечислением. Это и есть проверка твоей работы: план
|
||||
сверяется с `ls docs/` за секунду, и пропущенный документ виден без рассуждения.
|
||||
`.av-dev.toml` — единственное исключение: служебный файл, не документ, в плане
|
||||
не упоминается.
|
||||
|
||||
**Категории `источник` и `процессный` закрыты — они перечислены выше поимённо.**
|
||||
Открыта только `тема`. Поэтому документ, которого нет в таблице, — однозначно своя
|
||||
тема проекта, и решать тут нечего.
|
||||
|
||||
Раньше правило было плоским: «каждый файл в `docs/` — тема». По нему выходило,
|
||||
что `docs/passport.md` заводит тему `passport`, которая дублирует работу темы
|
||||
`architecture`, — или что паспорт не попадает в план вовсе. Обе ветки плохи, и
|
||||
обе случались.
|
||||
|
||||
## Правило 2 — ядро тем и проектные темы
|
||||
|
||||
Шесть тем есть у любого проекта, приведённого к канону. Их ты называешь **всегда**,
|
||||
даже когда дома нет:
|
||||
|
||||
| Тема | Дом | Что она спрашивает |
|
||||
|---|---|---|
|
||||
| `requirements` | `openspec/specs/`, дельты change | делает ли код то, что заказано, и только это |
|
||||
| `autotests` | `CLAUDE.md`: семантика гейта, команды | проверено ли машиной и хватает ли проверок |
|
||||
| `conventions` | `docs/conventions.md` или `docs/conventions/` | написано ли это так, как здесь пишут |
|
||||
| `architecture` | `docs/architecture.*` + источник `passport.*` | цело ли устройство: понятия и границы |
|
||||
| `security` | `docs/security.*` | что сделает недоверенный вход |
|
||||
| `operations` | `docs/architecture.*`, раздел эксплуатации, + источник `database.*` | что будет через неделю на проде |
|
||||
|
||||
**У трёх тем ядра дома в `docs/` нет вовсе, и это не пробел.** `requirements`
|
||||
живёт в `openspec/`, `autotests` — в `CLAUDE.md`, `operations` — разделом внутри
|
||||
`architecture.*`. Имя темы не выводится из имени файла, и обратно тоже.
|
||||
|
||||
**Список тем открытый.** Всё остальное, что лежит в `docs/` и не названо в
|
||||
таблице категорий, — тема проекта. Завёл `docs/accessibility.md` — появилась тема
|
||||
`accessibility`. Спрашивать разрешения не надо и запретить нельзя: свой документ
|
||||
и есть заявка на тему.
|
||||
|
||||
Тема из директивы `CLAUDE.md`/`AGENTS.md`, у которой нет документа, тоже
|
||||
объявляется: дом — сама директива, и в раздаче она идёт как **тема проекта**, то
|
||||
есть к `basics`. Скажи это строкой, чтобы исполнитель не оказался неназванным.
|
||||
|
||||
**Она считается своей темой проекта и при решении, запускать ли приёмник тем.**
|
||||
Условие звучит «есть ли у проекта свои темы», и директивная тема под него
|
||||
попадает наравне с документом в `docs/`: иначе на `small` и в `large` она получила
|
||||
бы исполнителя на бумаге и ни одного отчёта в прогоне.
|
||||
|
||||
## Правило 3 — адреса, а не пересказ
|
||||
|
||||
**Ты передаёшь проходу адрес и раздел, а не содержание.**
|
||||
|
||||
- годится: «тема `security`, дом `docs/security.md`, периметр в первом абзаце;
|
||||
вопросы проекта по теме — дословно вот эти два»;
|
||||
- **не годится**: «в проекте контур доверенный, наружу торчит только приём».
|
||||
|
||||
Причина не в экономии. Проект однажды уже держал файл-посредник между
|
||||
документами и проходами и убрал его: второй дом для тех же фактов расходится с
|
||||
первым и при этом выглядит актуальным. Твой пересказ — тот же посредник, только
|
||||
живущий один прогон. Проход, получивший проинтерпретированный периметр, не
|
||||
заметит, что интерпретация неверна.
|
||||
|
||||
Исключение ровно одно и полезное: **отсутствие дома**. «Тема `operations`
|
||||
заявлена, `docs/database.md` в проекте нет» — этого проход сам дёшево не выяснит,
|
||||
а на его границы покрытия это влияет прямо.
|
||||
|
||||
## Правило 4 — две оси, метка как максимум
|
||||
|
||||
**Ты меряешь изменение по двум независимым осям и называешь обе.** Метка — не
|
||||
ответ на один вопрос, а максимум по двум измерениям.
|
||||
|
||||
Ниже рабочая выжимка. Дом правила — скилл `av-dev:code-review`,
|
||||
`references/review-levels.md`: там разобрано, почему оси именно эти, чем `small`
|
||||
дешевле `medium` и какие доли служат проверкой правила. Открывай его, когда
|
||||
метка **спорная или оспорена**; на обычной задаче хватает того, что здесь.
|
||||
|
||||
**Ось «размер» — про объём: сколько мест трогается.**
|
||||
|
||||
- **малое** — помещается в один узел;
|
||||
- **среднее** — несколько узлов одного слоя;
|
||||
- **крупное** — несколько слоёв разом, перенос ответственности между ними,
|
||||
перекладывание существующего кода в новую форму.
|
||||
|
||||
**Ось «сложность» — про неизвестность: знаем ли мы форму решения заранее.**
|
||||
|
||||
- **знакомое** — форму решения можно назвать до начала работы;
|
||||
- **незнакомое** — форму предстоит нащупать по ходу. Признак один и
|
||||
проверяемый: **перед работой нельзя назвать, какие узлы будут тронуты**.
|
||||
|
||||
<!-- копия: матрица-метки из av-dev/skills/code-review/references/review-levels.md -->
|
||||
|
||||
| | **знакомое** — форму решения можно назвать до начала | **незнакомое** — форму предстоит нащупать по ходу |
|
||||
|---|---|---|
|
||||
| **малое** — один узел | `small` | `large` |
|
||||
| **среднее** — несколько узлов одного слоя | `medium` | `large` |
|
||||
| **крупное** — несколько слоёв, перенос ответственности, большой рефакторинг | `large` | `large` |
|
||||
|
||||
<!-- /копия: матрица-метки -->
|
||||
|
||||
**Метка — не синоним размера, и это главная ловушка таблицы.** Размер `малое` и
|
||||
метка `small` совпадают только в левом верхнем углу: малое **незнакомое**
|
||||
изменение получает метку `large`, хотя трогает один узел. Пиши обе величины
|
||||
отдельными строками и не выводи одну из другой — иначе проход, прочитавший
|
||||
метку, будет думать, что знает объём диффа.
|
||||
|
||||
**Опирайся на факты, а не на впечатление.** Обе оси выводятся из корпуса оценки
|
||||
— пяти источников выше, — и **каждая цифра в обосновании привязана к источнику
|
||||
поимённо**: «размер средний: `tasks.md` даёт шесть шагов в двух узлах». Фраза
|
||||
«изменение выглядит средним» обоснованием не является. Проектные уточнения — в `docs/review.md`,
|
||||
подраздел «Триггеры метки», **тремя списками**: «крупное здесь» и «незнакомое
|
||||
здесь» поднимают метку по своей оси, «мелкое здесь» опускает до `small`. Третий
|
||||
список один на обе оси: вниз метку опускает только совпадение обеих сразу.
|
||||
Читай все три — список, который ты не прочёл, это настройка проекта, не
|
||||
сработавшая молча.
|
||||
|
||||
**Диффа у тебя нет — кода ещё нет.** Не пытайся его считать и не жди его.
|
||||
|
||||
**Отрицательный тест `small`:** что после мерджа не откатывается обратной правкой
|
||||
— миграция схемы и данных, формат на диске, публичный контракт, имя, которое
|
||||
разойдётся, — не `small`, каким бы малым ни было изменение. Тест жёсткий, и вот
|
||||
почему: на `small` приёмник тем не запускается, а вопросы «обратима ли миграция»
|
||||
и «что с записями новой версии после отката» задаёт именно он. С этой меткой их
|
||||
не задаст никто.
|
||||
|
||||
**Спорный случай решается вниз.** Между `medium` и `large` бери `medium`,
|
||||
между `small` и `medium` бери `medium`. Ожидаемая доля `large` — 5–10% задач;
|
||||
если ты выбираешь его чаще, ты выбираешь по ощущению важности, а не по факту.
|
||||
|
||||
**Размер, сложность и метка объявляются с обоснованием, и обоснование
|
||||
обязательно всегда** — не только когда ты отступаешь от умолчания. По строке на
|
||||
ось: какой факт дал этот ответ. Поднять и понизить ты вправе одинаково; молча —
|
||||
ни то ни другое.
|
||||
|
||||
**Метка, названная тобой, действует до конца задачи и после кода не
|
||||
пересматривается.** Второй раз тебя не позовут — кроме случая, когда правка после
|
||||
ревью дизайна изменила сами дельта-спеки: план выведен из них, и план по
|
||||
отменённым требованиям назовёт не те темы.
|
||||
|
||||
## Правило 5 — раздача тем на обеих стадиях
|
||||
|
||||
**Ревью дизайна — состав по метке, тем не раздаётся.** До кода закрывать темы
|
||||
нечем: проверяется предложение, а не изменение.
|
||||
|
||||
| Метка | Проходы на предложении |
|
||||
|---|---|
|
||||
| `small` | `specs` |
|
||||
| `medium` | `specs`, `rubric` |
|
||||
| `large` | `specs`, `rubric`, `architecture` + вопрос автору о трёх формах решения |
|
||||
|
||||
**Ревью кода — раздача тем.** Кто закрывает тему, зависит от метки. Раскладка
|
||||
жёсткая, выдумывать её не надо:
|
||||
|
||||
<!-- копия: тема-метка-глубина из av-dev/skills/code-review/SKILL.md -->
|
||||
|
||||
| Тема | `small` | `medium` | `large` |
|
||||
|---|---|---|---|
|
||||
| `requirements` | `specs`, сверка | `specs`, разбор | `specs`, разбор |
|
||||
| `autotests` | `autotests` | `autotests` | `autotests` |
|
||||
| `conventions` | `code`, сверка | `code`, разбор | `code`, разбор |
|
||||
| `architecture` | `code`, сверка по инвариантам | `basics`, разбор | `architecture`, доказательство |
|
||||
| `security` | `code`, сверка по инвариантам | `basics`, разбор | `adversary`, доказательство |
|
||||
| `operations` | `code`, сверка по инвариантам | `basics`, разбор | `ops`, доказательство |
|
||||
| тема проекта | `basics`, сверка | `basics`, разбор | `basics`, разбор |
|
||||
|
||||
<!-- /копия: тема-метка-глубина -->
|
||||
|
||||
Две глубины, которые ты назначаешь:
|
||||
|
||||
- **сверка** — открыть дом, открыть дифф, сравнить. Один-два вопроса на тему,
|
||||
ответ «неприменимо» дешёвый;
|
||||
- **разбор** — построить сценарий рассуждением, ничего не запуская. Два-три
|
||||
вопроса на тему.
|
||||
|
||||
Третья глубина, **доказательство** (прогнать, померить, построить путь), тобою
|
||||
не назначается: она есть только в `large` и принадлежит именным проходам. В
|
||||
таблице она стоит **справочно**, чтобы состав читался целиком; в своём плане ты
|
||||
против этих трёх тем пишешь `доказательство` без выбора.
|
||||
|
||||
**На `small` у трёх тем ядра дом другой, а не глубина меньше.** `security`,
|
||||
`operations` и `architecture` смотрятся против **инвариантов `CLAUDE.md`**, а не
|
||||
против своих домов, и закрывает их `code` с потолком 1 находка на все три. Так и
|
||||
пиши в плане: дом — `CLAUDE.md`, инварианты. Приписывать им дом
|
||||
`docs/security.md` было бы враньём — по этому адресу на `small` никто не пойдёт.
|
||||
|
||||
**`basics` запускается тогда и только тогда, когда ему есть что принимать.**
|
||||
|
||||
- на `medium` — всегда: три темы ядра плюс свои темы проекта;
|
||||
- на `small` и в `large` — только при своих темах проекта.
|
||||
|
||||
Нет своих тем — в плане строка, и она разная: в `large` «`basics` не запускается:
|
||||
все темы разобраны именными проходами», на `small` «`basics` не запускается: темы
|
||||
ядра закрыты сверкой по инвариантам внутри `code`». Молчащего пропуска здесь быть
|
||||
не может.
|
||||
|
||||
**Тема без дома исполнителя не теряет.** Нет `docs/security.md` — тема `security`
|
||||
всё равно идёт строкой, с пометкой «дома нет», и её всё равно кто-то закрывает:
|
||||
вопросы задаются по коду, ответы формулируются условиями. Падает **глубина**, и
|
||||
только она. Строки с исполнителем «никто» в твоём плане быть не может ни при
|
||||
каких обстоятельствах: тема без исполнителя — это и есть молчащий пропуск.
|
||||
|
||||
## Формат вывода
|
||||
|
||||
Строго этот, он уезжает в отчёт целиком и служит границами покрытия:
|
||||
|
||||
```
|
||||
размер: среднее — tasks.md: 6 шагов в двух узлах; дельты трогают 2 capability;
|
||||
«Затрагивает» называет 3 узла (взято большее — tasks.md)
|
||||
сложность: знакомое — «Затрагивает» называет узлы поимённо до начала работы;
|
||||
design.md разбирает одну форму решения, альтернатив не рассматривал
|
||||
метка: medium — максимум по осям; ни одна не дала large
|
||||
|
||||
корпус: запись задачи, proposal.md, design.md, tasks.md, дельта-спеки — все пять
|
||||
|
||||
ревью дизайна: specs, rubric
|
||||
|
||||
ревью кода, темы:
|
||||
тема дом глубина закрывает
|
||||
requirements openspec/changes/<id>/specs/ разбор specs
|
||||
autotests CLAUDE.md, семантика гейта — autotests
|
||||
conventions docs/conventions/ разбор code
|
||||
architecture docs/architecture.md разбор basics
|
||||
+ источник docs/passport.md
|
||||
security docs/security.md разбор basics
|
||||
operations docs/architecture.md, «Эксплуатация» разбор basics
|
||||
дома нет: docs/database.md отсутствует
|
||||
|
||||
процессные: tasks/, docs/review.md, docs/adr/, docs/research/
|
||||
директивы: CLAUDE.md найден, AGENTS.md отсутствует
|
||||
```
|
||||
|
||||
Обрати внимание на две строки этого образца, потому что обе раньше писались
|
||||
неверно. `docs/passport.md` **не** заводит своей строки и **не** пропадает — он
|
||||
стоит источником внутри темы `architecture`. Отсутствие `docs/database.md` **не**
|
||||
порождает псевдотемы с исполнителем «никто» — оно понижает глубину темы
|
||||
`operations`, и та остаётся за своим исполнителем.
|
||||
|
||||
Дальше — блок вопросов по темам из `docs/review.md`, **дословно**, с указанием,
|
||||
кому какой уходит. Вопрос, адресованный не теме (`passport`, `database`, `adr`,
|
||||
`research`, `review`), не раздавай: таких тем нет. Скажи об этом строкой — это
|
||||
находка о настройке проекта, и чинится она правкой `docs/review.md`.
|
||||
|
||||
И обязательная строка:
|
||||
|
||||
```
|
||||
## Coverage of this pass
|
||||
- документов в docs/ найдено N, все N разнесены: тем M, источников K, процессных L
|
||||
- корпус оценки: какие из пяти источников прочитаны, какие отсутствуют и что это дало осям
|
||||
- расхождение источников по размеру: <какие цифры и какая взята, или «нет»>
|
||||
- тем без дома: <перечень или «нет»>
|
||||
- вопросов по темам роздано: <число>; адресованных не теме: <перечень или «нет»>
|
||||
- чего не смотрел: содержимого документов — по построению; кода и диффа — их ещё нет
|
||||
```
|
||||
|
||||
**Строка про корпус обязательна и тогда, когда прочитаны все пять.** Отсутствие
|
||||
источника меняет обе оси, и молчащий пропуск здесь дороже прочих: он двигает не
|
||||
одну тему, а состав обоих прогонов сразу.
|
||||
|
||||
## Чего ты не делаешь
|
||||
|
||||
- **не судишь код** — ни одной находки по существу изменения;
|
||||
- **не пересказываешь документы** (правило 3);
|
||||
- **не выдумываешь тем** — тема приходит из своего документа проекта или из
|
||||
директивы, а не из представления о том, что стоило бы проверить, и **не из
|
||||
документа категорий `источник` и `процессный`**;
|
||||
- **не оставляешь тему без исполнителя** — строки «закрывает: никто» не бывает;
|
||||
- **не решаешь за человека о понижении**: понизить метку ты вправе, но
|
||||
обоснование идёт в отчёт и читается человеком.
|
||||
|
||||
## Ограничения
|
||||
|
||||
Только чтение. `Bash` — для `ls` и `grep` по заголовкам. Ничего не запускай,
|
||||
ничего не редактируй. `git diff` тебе не нужен: на момент твоего запуска кода
|
||||
ещё нет.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-specs
|
||||
description: "Сверка изменения с дельта-спеками в обе стороны — spec→code (каждое требование реализовано и подтверждено тестом) и, что важнее, code→spec (поведение, которое код имеет, а спека не заказывала: тихие ветки, самодеятельные дефолты, проглоченные ошибки, отброшенные поля, ретраи «на всякий случай»). Плюс границы спеки — что она не определяет и что пришлось домыслить. Работает в двух режимах: дизайн/спеки ДО кода и код против спек ПОСЛЕ apply. Только чтение."
|
||||
description: "Сверка изменения с дельта-спеками в обе стороны — spec→code (каждое требование реализовано и подтверждено тестом) и, что важнее, code→spec (поведение, которое код имеет, а спека не заказывала: тихие ветки, самодеятельные дефолты, проглоченные ошибки, отброшенные поля, ретраи «на всякий случай»). Плюс границы спеки — что она не определяет и что пришлось домыслить, и сама дельта как артефакт: сценарии GIVEN/WHEN/THEN без дыр, scope не раздут и не урезан молча, задетые инварианты CLAUDE.md отражены поимённо. Идёт по готовому коду, после apply; вход постоянный и потолка находок не имеет. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -32,20 +32,15 @@ Development на OpenSpec). Оптика — требования, а не ст
|
||||
похожей на доказанную, ничего не доказывая. Скажи об этом строкой в границах
|
||||
покрытия.
|
||||
|
||||
**Сколько ты читаешь, зависит от метки — она приходит в задании.**
|
||||
**Вход у тебя постоянный, и метки, которая его сужала бы, больше нет.** Читаешь
|
||||
дельта-спеку change, затронутые актуальные спеки, `design.md` и `tasks.md`
|
||||
change, `docs/architecture.md`, `docs/passport.md` и инварианты `CLAUDE.md`.
|
||||
|
||||
| | `small` | `medium` и `large` |
|
||||
|---|---|---|
|
||||
| источник требований | **только дельта-спека change** | дельта + затронутые актуальные спеки |
|
||||
| `design.md`, `tasks.md` change | не читаешь | читаешь |
|
||||
| `docs/architecture.md`, `passport.md` | не читаешь | читаешь |
|
||||
| `CLAUDE.md`, инварианты | читаешь всегда | читаешь всегда |
|
||||
| потолок находок | **3** | нет |
|
||||
|
||||
На `small` это значит: сверка идёт против того, что заказано **этим изменением**,
|
||||
и только. Что в актуальных спеках уже было и как это соотносится с обзором
|
||||
архитектуры — не твой вопрос с этой меткой, и так и скажи в границах покрытия.
|
||||
Потолок, если сработал, объяви: сколько осталось за срезом.
|
||||
**Потолка находок у тебя тоже нет.** Причина в цене ошибки: направление
|
||||
`code → spec` требует заметить **отсутствие** — тихий фолбэк, самодеятельный
|
||||
дефолт, проглоченную ошибку, — и срезанная по потолку находка такого рода не
|
||||
оставляет следа нигде. Список из десяти расхождений со спекой длинный, но
|
||||
честный; список из трёх выглядит так же, а молчит о семи.
|
||||
|
||||
Пути спек жёсткие: актуальные — `openspec/specs/<capability>/spec.md`, дельты —
|
||||
`openspec/changes/<id>/specs/`. Карта «что нужно проходу → где лежит» —
|
||||
@@ -63,31 +58,37 @@ Development на OpenSpec). Оптика — требования, а не ст
|
||||
намерение, а спека нормирует. Расхождение между proposal и дельтой — само по себе
|
||||
находка.
|
||||
|
||||
**Живого change нет — ты не запускаешься.** Оба режима стоят на дельта-спеке; без
|
||||
неё сверять нечего, и это строка отказа, а не повод взять источником актуальные
|
||||
спеки: они описывают, что система делает вообще, а не что заказало это изменение.
|
||||
**Живого change нет — ты не запускаешься.** Вся твоя работа стоит на дельта-спеке;
|
||||
без неё сверять нечего, и это строка отказа, а не повод взять источником
|
||||
актуальные спеки: они описывают, что система делает вообще, а не что заказало это
|
||||
изменение.
|
||||
|
||||
Дополнительно поднимаешь **с метки `medium`**: `design.md` и `tasks.md`
|
||||
change, затронутые актуальные спеки. Инварианты из `CLAUDE.md` — при любой метке. Если тема ещё не перенесена в спеки и живёт только в
|
||||
`docs/architecture.md` — источник истины там, и это фиксируется в границах
|
||||
покрытия.
|
||||
Дополнительно поднимаешь: `design.md` и `tasks.md` change, затронутые актуальные
|
||||
спеки, инварианты из `CLAUDE.md`. Если тема ещё не перенесена в спеки и живёт
|
||||
только в `docs/architecture.md` — источник истины там, и это фиксируется в
|
||||
границах покрытия.
|
||||
|
||||
## Режим 1 — дизайн/спеки ДО кода
|
||||
## Дельта как артефакт
|
||||
|
||||
Проверяешь change как артефакт: полнота покрытия постановки; сценарии
|
||||
`GIVEN/WHEN/THEN` без дыр, противоречий и недостижимых веток; scope не раздут и
|
||||
не урезан молча; согласованность с текущими спеками и нарезкой capability; в
|
||||
спеке отражены **задетые инварианты из `CLAUDE.md`** — поимённо, а не
|
||||
«безопасность учтена».
|
||||
Работа идёт по готовому коду, но саму дельту ты тоже судишь — потому что код
|
||||
сверяется с ней, и дырявая спека делает сверку бессмысленной: полнота покрытия
|
||||
постановки; сценарии `GIVEN/WHEN/THEN` без дыр, противоречий и недостижимых
|
||||
веток; scope не раздут и не урезан молча; согласованность с текущими спеками и
|
||||
нарезкой capability; в спеке отражены **задетые инварианты из `CLAUDE.md`** —
|
||||
поимённо, а не «безопасность учтена».
|
||||
|
||||
Прогоняй `openspec validate --strict <id>` сам — это оракул, а не догадка.
|
||||
|
||||
## Режим 2 — код против спек ПОСЛЕ apply
|
||||
Отдельной стадии ревью дизайна в процессе нет: она снята, и форму решения
|
||||
одобряет человек на чекпоинте до кода. Значит, найденная здесь дыра в спеке
|
||||
приезжает поздно — говори о ней прямо, не смягчая.
|
||||
|
||||
## Код против спек
|
||||
|
||||
Сверка **двунаправленная**. Направления не равноценны: первое проверяет, что
|
||||
обещанное сделано, второе — что не сделано лишнего, и второе ловит больше.
|
||||
|
||||
### 2.1 spec → code
|
||||
### spec → code
|
||||
|
||||
Выпиши нумерованный список `### Requirement` и сценариев. Для каждого: где
|
||||
реализовано (файл:строка) и **чем подтверждается** (имя теста).
|
||||
@@ -98,7 +99,7 @@ change, затронутые актуальные спеки. Инвариант
|
||||
отдельно, подтверждены ли они **реальными данными** в `testdata`: синтетический
|
||||
вход доказывает разбор придуманной формы, а не пришедшей.
|
||||
|
||||
### 2.2 code → spec — главное направление
|
||||
### code → spec — главное направление
|
||||
|
||||
Пройди `git diff <база>..HEAD` и выпиши **всё поведение, которого нет в дельте**.
|
||||
Это системная болезнь агентского кода: он тихо добавляет то, что «кажется
|
||||
@@ -126,7 +127,7 @@ change, затронутые актуальные спеки. Инвариант
|
||||
- **подмена требования** → находка **в код**: поведение противоречит заказанному
|
||||
либо маскирует отказ, который спека требует показать.
|
||||
|
||||
### 2.3 Границы спеки
|
||||
### Границы спеки
|
||||
|
||||
Отдельной секцией: что дельта **не определяет**, а код был вынужден домыслить —
|
||||
пустой вход, нулевые значения, конкурентная операция над тем же ключом, повторный
|
||||
@@ -134,7 +135,7 @@ change, затронутые актуальные спеки. Инвариант
|
||||
незнакомая форма входа, смешанная гранулярность. Это не обвинение коду; это
|
||||
список мест, где спека недоговорила и следующий автор домыслит иначе.
|
||||
|
||||
### 2.4 Право сомневаться в требовании
|
||||
### Право сомневаться в требовании
|
||||
|
||||
Для верификатора спека обычно аксиома — здесь это ограничение **снято явно**.
|
||||
Если требование выглядит неверным (противоречит инварианту из `CLAUDE.md`, делает
|
||||
@@ -163,9 +164,10 @@ change, затронутые актуальные спеки. Инвариант
|
||||
|
||||
```
|
||||
## Coverage of this pass
|
||||
- метка: <small | medium | large>; с меткой small — «источник только дельта-спека, актуальные спеки и обзор не читались»
|
||||
- проверено: <какие Requirements, какие файлы диффа прочитаны>
|
||||
- потолок (только small): N/3 — и что осталось за срезом
|
||||
- источники: дельта, актуальные спеки, design/tasks, architecture, passport, инварианты — что из этого нашлось
|
||||
- вопросы проекта по теме requirements: <вопрос → ответ, дословно — или «задание их не принесло»>
|
||||
- отложено в av-dev:code-deep-review: <что доказывается только прогоном или входом шире диффа — или «нечего»>
|
||||
- не проверялось и почему: ...
|
||||
- требование против записанного наблюдения не проверялось: docs/research/ — процессный документ, прогон его не открывает
|
||||
- принципиально недоступно этому проходу: форма решения, идиоматичность, эксплуатация
|
||||
@@ -175,3 +177,15 @@ change, затронутые актуальные спеки. Инвариант
|
||||
|
||||
Только чтение и анализ. `openspec validate` запускать можно и нужно. Не
|
||||
редактируй код и спеки, не архивируй change.
|
||||
|
||||
## Вопросы проекта по теме
|
||||
|
||||
**`docs/review.*` держит подраздел «Вопросы по темам», и вопрос по теме
|
||||
`requirements` — твой.** Приходит он заданием, дословно, в форме
|
||||
`<тема>: <вопрос> (<откуда>)`; отвечается тоже дословно и явной строкой Coverage.
|
||||
Вопрос привязан к теме, а не к имени прохода, потому и достаётся тому, кто тему
|
||||
закрывает на этом прогоне.
|
||||
|
||||
Задание вопросов не принесло — скажи строкой. Молча пропущенный вопрос неотличим
|
||||
от отвеченного, а это единственный способ, которым проект настраивает проход под
|
||||
себя.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-triage
|
||||
description: "Обязательный финальный проход конвейера ревью — единственный, кто агрегирует. Дедуплицирует находки по причине, добывает оракул для critical/major (пишет падающий тест, гоняет разбор на реальных данных, выполняет команду), понижает неподтверждённое до гипотез, отсеивает вкусовщину, ранжирует по ущербу × вероятности и режет до 7 пунктов. Помечает каждую находку «инлайн» или «развилка» для оркестратора. Сверяет план с пришедшими отчётами: тема, стоявшая в плане и оставшаяся без отчёта, — находка о самом прогоне; на прогоне без метки план даёт сценарий обслуживания, а не разметчик. Формирует итоговый отчёт с планом, перечнем проходов и обязательной секцией границ покрытия."
|
||||
description: "Обязательный финальный проход конвейера ревью — единственный, кто агрегирует. Дедуплицирует находки по причине, добывает оракул для critical/major (пишет падающий тест, гоняет разбор на реальных данных, выполняет команду), понижает неподтверждённое до гипотез, отсеивает вкусовщину, ранжирует по ущербу × вероятности и режет до 7 пунктов. Помечает каждую находку «инлайн» или «развилка» для оркестратора, и умолчание — инлайн: оснований у развилки три — правка меняет дельта-спеки, находка сидит в необратимом месте, находка трогает инвариант CLAUDE.md. Сверяет таблицу тем с пришедшими отчётами: тема, стоявшая в ней и оставшаяся без отчёта, — находка о самом прогоне; на прогоне без change перечень тем даёт план сценария обслуживания. Сводит строки «отложено в av-dev:code-deep-review» в одну секцию отчёта. Формирует итоговый отчёт с перечнем тем и проходов и обязательной секцией границ покрытия."
|
||||
tools: Read, Grep, Glob, Bash, Write
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -21,26 +21,50 @@ color: yellow
|
||||
|
||||
## Вход
|
||||
|
||||
Сырые выводы всех запущенных проходов, `git diff <база>..HEAD`, **план прогона**
|
||||
Сырые выводы всех запущенных проходов, `git diff <база>..HEAD`, **перечень тем**
|
||||
и режим. Дельта-спеки — по мере надобности.
|
||||
|
||||
План — таблица «тема → дом → глубина → кто закрывает». Он твой главный инструмент
|
||||
сверки: ты единственный, кто видит и то, что заявлено, и то, что пришло.
|
||||
Перечень тем — таблица «тема → кто закрывает → против чего». Он твой главный
|
||||
инструмент сверки: ты единственный, кто видит и то, что заявлено, и то, что
|
||||
пришло.
|
||||
|
||||
**Откуда план приходит, зависит от режима, и режимов два.**
|
||||
**Откуда перечень приходит, зависит от того, кто тебя позвал.**
|
||||
|
||||
- **С меткой** — план собрал `review-scope` (один запуск после `propose`), и к
|
||||
таблице прилагаются размер, сложность и метка с обоснованием.
|
||||
- **Без метки** — так идёт прогон сценария обслуживания: изменение не меняет
|
||||
поведения, размечать нечего, и разметчик не запускается вовсе. План
|
||||
**фиксирован сценарием** (`av-dev:code-resolve`, `references/maintain.md`), а
|
||||
размера, сложности и метки не существует. Не ищи их и не подставляй: в отчёте
|
||||
на их месте — строка «прогон без метки, план сценария».
|
||||
- **По change** — обычный прогон цикла задачи. Перечень постоянный, он живёт в
|
||||
конвейере (`av-dev:code-review`, раздел «Состав прогона») и на каждой задаче
|
||||
один и тот же. Метки у прогона нет: считать её было нечем и незачем — состав от
|
||||
неё больше не зависит.
|
||||
- **Без change** — прогон сценария обслуживания: изменение не меняет поведения,
|
||||
дельта-спек нет, и перечень **фиксирован сценарием** (`av-dev:code-resolve`,
|
||||
`references/maintain.md`). Тема `requirements` в нём отсутствует за отсутствием
|
||||
предмета.
|
||||
- **Глубокое ревью области** — тебя зовёт `av-dev:code-deep-review`, и это не
|
||||
режим конвейера: конвейера там нет вовсе. Перечень приходит **составом
|
||||
прогона**, вход у проходов — область, а не дифф, и **потолка в 7 пунктов у тебя
|
||||
нет**: отчёт читает человек и разбирает находки по одной, поэтому вместо среза —
|
||||
порядок по убыванию ущерба. Остальные шаги идут как обычно, включая оракул и
|
||||
границы покрытия.
|
||||
|
||||
**Плана нет ни от разметчика, ни от сценария — ты не запускаешься, и исключений
|
||||
нет.** Сверка заявленного с пришедшим — твоя единственная защита от молчащего
|
||||
пропуска, и без плана она не выполняется вовсе. Отчёт, собранный без неё,
|
||||
выглядит полным ровно настолько же, насколько и неполный.
|
||||
Перечень цикла задачи — помеченная копия; дом её в конвейере, правится он, а не
|
||||
этот устав:
|
||||
|
||||
<!-- копия: тема-глубина из av-dev/skills/code-review/SKILL.md -->
|
||||
|
||||
| Тема | Кто закрывает | Против чего и как |
|
||||
|---|---|---|
|
||||
| `autotests` | `autotests` | запуск: гейт проекта и логи его шагов |
|
||||
| `requirements` | `specs` | разбор: дельта-спеки change, сверка в обе стороны |
|
||||
| `conventions` | `code` | разбор: дома конвенций проекта |
|
||||
| техника | `code` | разбор: дефект, который сработает сам |
|
||||
| `security`, `operations`, `architecture` | `code` | **сверка с записанными инвариантами `CLAUDE.md`** — и только |
|
||||
| тема проекта | `basics` | разбор: дом темы против диффа |
|
||||
|
||||
<!-- /копия: тема-глубина -->
|
||||
|
||||
**Перечня нет ни того ни другого — ты не запускаешься, и исключений нет.** Сверка
|
||||
заявленного с пришедшим — твоя единственная защита от молчащего пропуска, и без
|
||||
перечня она не выполняется вовсе. Отчёт, собранный без неё, выглядит полным ровно
|
||||
настолько же, насколько и неполный.
|
||||
|
||||
Из документов проекта тебе нужны:
|
||||
|
||||
@@ -153,17 +177,31 @@ severity:
|
||||
```
|
||||
|
||||
- **инлайн** — оркестратор чинит сам, не спрашивая и не логируя. Правка локальна,
|
||||
решение однозначно, объём — по размеру находки.
|
||||
- **развилка** — цена сопоставима с переработкой, либо меняется scope, либо
|
||||
трогается инвариант из `CLAUDE.md`, либо надо менять спеку. Формулируй готовым
|
||||
вопросом с 2–3 вариантами: оркестратор перенесёт его почти дословно.
|
||||
решение однозначно, объём — по размеру находки. **Это умолчание, и оно
|
||||
широкое:** цикл задачи устроен так, чтобы человек читал сводку, а не разбирал
|
||||
список замечаний.
|
||||
- **развилка** — узкий выход, и оснований у него три: правка **меняет
|
||||
дельта-спеки** (то есть отменяет одобренное человеком), находка сидит в
|
||||
**необратимом** месте (миграция, формат на диске, публичный контракт, имя,
|
||||
разошедшееся по базе), находка трогает **инвариант** `CLAUDE.md`. Формулируй
|
||||
готовым вопросом с 2–3 вариантами: оркестратор перенесёт его почти дословно.
|
||||
|
||||
Сомневаешься — ставь `развилка`. Ошибка в сторону лишнего вопроса дешевле
|
||||
незаказанной переработки.
|
||||
**Сомневаешься — ставь `инлайн`**, если ни одно из трёх оснований не сработало.
|
||||
Прежде правило было обратным: «сомневаешься — развилка, лишний вопрос дешевле
|
||||
незаказанной переработки». Оно верно там, где вопрос ждёт своей очереди в
|
||||
трекере, и неверно там, где его читает человек, ведущий задачу прямо сейчас:
|
||||
десяток вопросов на прогон превращает цикл в разбор, ради которого существует
|
||||
отдельный скилл. Переработка при этом остаётся защищённой — она либо меняет
|
||||
спеки, либо трогает инвариант, а это уже названные основания.
|
||||
|
||||
## Сверка плана с исходом — обязательна
|
||||
**Находка не для этого мерджа идёт в урожай, а не в развилку.** Отложенный
|
||||
`major`, развилка, решённая «потом», пачка `nit` — секция `Урожай`:
|
||||
формулировка, оракул, откуда взялась. Задачи из неё заводит не конвейер и не
|
||||
оркестратор, а человек своим словом.
|
||||
|
||||
Сводка отчёта воспроизводит **план целиком** и против каждой темы ставит исход:
|
||||
## Сверка перечня тем с исходом — обязательна
|
||||
|
||||
Сводка отчёта воспроизводит **перечень целиком** и против каждой темы ставит исход:
|
||||
закрыта таким-то проходом (сколько находок) / отчёта не пришло / дома у темы нет.
|
||||
Сверяй сам, а не доверяй тому, что тебе подали: пропуск **не отличим от прохода
|
||||
без находок**, и назвать его больше некому.
|
||||
@@ -173,27 +211,29 @@ severity:
|
||||
показывал вовсе: список запущенного отвечал «все, кто должен был, отработали», а
|
||||
вопрос «что именно осталось непроверенным» задать было нечем.
|
||||
|
||||
Отдельно проверь **сигнал о заниженной метке** — его подаёт `review-code` при
|
||||
любой метке и `review-basics`, когда запускается. Пришёл хоть от одного — веди
|
||||
его в сводку отдельной строкой, а не в общий список находок: метку выбирал
|
||||
`review-scope`, а не они и не ты, значит сигнал независим. Пришли оба — это одна
|
||||
строка с двумя названными проходами, а не два пункта: согласие проходов приоритет
|
||||
повышает, `confidence` нет.
|
||||
Отдельно проверь **сигнал «это изменение просит глубокого ревью»** — его подаёт
|
||||
`review-code` всегда и `review-basics`, когда запускается. Пришёл хоть от одного
|
||||
— веди его в сводку отдельной строкой, а не в общий список находок: он про сам
|
||||
прогон, а не про код. Пришли оба — это одна строка с двумя названными проходами,
|
||||
а не два пункта: согласие проходов приоритет повышает, `confidence` нет.
|
||||
|
||||
**Сигнала нет — тоже скажи строкой.** «Корректор метки отработал, возражений
|
||||
нет» и «корректор не запускался» — разные вещи, и отличить их по молчанию
|
||||
нельзя. **На прогоне без метки корректору нечего поднимать**, и это третье
|
||||
состояние: пиши «метки нет, корректор неприменим», а не «не запускался» —
|
||||
последнее читается как пропуск.
|
||||
**Сигнала нет — тоже скажи строкой.** «Проходы возражений не подали» и «проход не
|
||||
запускался» — разные вещи, и отличить их по молчанию нельзя.
|
||||
|
||||
**Строки «отложено в `av-dev:code-deep-review`» сведи в отдельную секцию** — тема,
|
||||
место, чем проверяется. Их пишут проходы, упёршиеся в предел цикла: нужен замер,
|
||||
нужен прогнанный путь, нужен вход шире диффа. Не сведённые в одно место, они
|
||||
растворяются по отчётам проходов, и повод позвать глубокое ревью не копится
|
||||
нигде. Нечего сводить — так и скажи строкой.
|
||||
|
||||
## Границы покрытия — не сокращаются
|
||||
|
||||
Финальная секция сводит границы всех проходов. Обязательно называет:
|
||||
|
||||
- **план: темы, их глубины и дома** — включая темы, у которых дома нет;
|
||||
- какие проходы запускались, на какой метке и в каком режиме;
|
||||
- какие **не** запускались и почему (метка, бюджет, недоступный инструмент,
|
||||
остановленный прогон);
|
||||
- **перечень тем, их глубины и дома** — включая темы, у которых дома нет;
|
||||
- какие проходы запускались и в каком режиме;
|
||||
- какие **не** запускались и почему (нет своих тем проекта, дифф не трогает код,
|
||||
недоступный инструмент, остановленный прогон);
|
||||
- что каждый запущенный проход **не мог проверить в принципе** — из его charter'а;
|
||||
- **что осталось целиком на человеке** — «Недоступно проверке» из `docs/review.*`,
|
||||
**двумя отдельными списками**: «не проверит ни один проход» и «перестали
|
||||
@@ -228,10 +268,15 @@ severity:
|
||||
нет.** Проход независимой реализации снят по стоимости, а не по замеру; «не
|
||||
знаю, чего не знаю» больше не достаёт никто.
|
||||
|
||||
Плюс **с меткой `small`** — пятая строка: темы `security`, `operations` и
|
||||
`architecture` сверялись только с записанными инвариантами `CLAUDE.md`, дома этих
|
||||
тем не открывались. Свойство, которого нет в инвариантах, с этой меткой не
|
||||
проверил никто.
|
||||
Плюс **пятая и шестая, обязательные на каждом прогоне цикла задачи**:
|
||||
|
||||
5. **Темы `security`, `operations` и `architecture` сверялись только с записанными
|
||||
инвариантами `CLAUDE.md`**, дома этих тем не открывались. Свойства, которого
|
||||
нет в инвариантах, не проверил никто. Разбор этих тем, построенный путь и
|
||||
снятое число живут в скилле `av-dev:code-deep-review`.
|
||||
6. **Форму решения не судил ни один проход.** Второй способ делать уже делаемое,
|
||||
лишний слой, интерфейс ради мока — это тот же скилл; в цикле форму одобряет
|
||||
человек на чекпоинте до кода.
|
||||
|
||||
Формулировка «критичных проблем не обнаружено» **запрещена** без этой секции: она
|
||||
потребляет ощущение проверенности, ничего не гарантируя, и это хуже, чем
|
||||
@@ -246,14 +291,15 @@ severity:
|
||||
## Формат вывода
|
||||
|
||||
Строго секциями из контракта: `Блокирует мердж` (≤3) / `Стоит исправить сейчас`
|
||||
(≤4) / `Гипотезы без доказательства` / `Promote candidates` / `Границы покрытия`.
|
||||
(≤4) / `Гипотезы без доказательства` / `Урожай` / `Отложено в
|
||||
av-dev:code-deep-review` / `Promote candidates` / `Границы покрытия`.
|
||||
|
||||
Перед секциями — сводка: режим прогона, состояние гейта, **план с исходом по
|
||||
каждой теме**, сколько находок пришло на вход и сколько осталось. На прогоне
|
||||
**с меткой** к этому добавляются размер, сложность и метка с обоснованием
|
||||
разметки; на прогоне **без метки** их место занимает строка «прогон без метки,
|
||||
план сценария обслуживания» — выдумывать метку задним числом нельзя, её никто
|
||||
не снимал.
|
||||
Перед секциями — сводка: режим прогона (`по change` или `без change`), состояние
|
||||
гейта, **перечень тем с исходом по каждой**, сколько находок пришло на вход и
|
||||
сколько осталось, сколько из них помечено `инлайн` и сколько `развилка`.
|
||||
Последнее число — способ увидеть, во что обходится прогон человеку: развилок
|
||||
больше двух на задачу значит, что либо задача не та, либо разметка действий
|
||||
съехала.
|
||||
|
||||
## Ограничения
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ color: green
|
||||
одной партии»), — находка: слово стоит, проверки нет. Число критериев считает
|
||||
`tasks.py check`, тебе оно неинтересно.
|
||||
|
||||
6. **Предписания процесса в теле нет.** «Делать с меткой medium», «взять
|
||||
6. **Предписания процесса в теле нет.** «Проверить вот таким проходом», «взять
|
||||
такой-то агент» — это выбор, который делают, увидев изменение, а не при
|
||||
постановке. Он же путь понизить требования решением, принятым до
|
||||
проектирования.
|
||||
|
||||
+57
-41
@@ -3,8 +3,20 @@
|
||||
**Это дом перечня, а не значений.** Что означает каждое значение и как оно
|
||||
работает, знает владелец оси — здесь только сама ось, её дом и **чего она не
|
||||
решает**. Второй пересказ механики разошёлся бы с первым; перечень же нужен
|
||||
целиком и в одном месте, потому что вопрос «а не задаёт ли это метку» задают из
|
||||
скилла, который метку не ведёт.
|
||||
целиком и в одном месте, потому что вопрос «а не задаёт ли это глубину ревью»
|
||||
задают из скилла, который ревью не ведёт.
|
||||
|
||||
**Одну ось перечень уже терял, и терял молча.** Метка задачи — `small`, `medium`,
|
||||
`large` — правила состав ревью кода, пока состав не стал постоянным; ось снята
|
||||
вместе с проходом, который её считал. Строка в журнале решений есть, а здесь от
|
||||
неё не осталось ничего — так и должно быть: перечень описывает то, что ветвится
|
||||
сегодня.
|
||||
|
||||
**Трёх осей он не досчитывал и в обратную сторону.** Глубина темы, разметка
|
||||
действия и род правки документа ветвили поведение годами, а в перечне их не было:
|
||||
каждая живёт в своём скилле, и оттуда её видно, а отсюда — нет. Ровно за этим
|
||||
перечень и заведён: вопрос «а не задаёт ли это глубину ревью» задают из скилла,
|
||||
который ревью не ведёт.
|
||||
|
||||
**Ось — это закрытый перечень значений, по которому что-то ветвится.** Признак
|
||||
проверяемый, и он отсекает похожее: темы ревью и документы проекта — списки
|
||||
@@ -20,9 +32,10 @@
|
||||
| тип записи | `feature` `fix` `chore` `research` | `task-track/SKILL.md`, «Тип записи» |
|
||||
| форма постановки | запись каталога · текст | `code-resolve/SKILL.md`, «Вход» |
|
||||
| сценарий | решение · обслуживание · разведка | `code-resolve/SKILL.md`, «Развилка» |
|
||||
| метка | `small` `medium` `large` | `code-review/SKILL.md`, «Метки» |
|
||||
| режим прогона | с меткой · без метки | здесь, ниже |
|
||||
| стадия ревью | дизайн · код | `code-review/SKILL.md`, «Ревью дизайна» |
|
||||
| режим прогона | по change · без change | здесь, ниже |
|
||||
| род правки документа | отражение · новое | `doc-sync/SKILL.md`, «Два рода правок» |
|
||||
| глубина темы | сверка · разбор · доказательство | `code-review/SKILL.md`, таблица тем |
|
||||
| разметка действия | инлайн · развилка | `code-review/SKILL.md`, «Что происходит с находками» |
|
||||
| категория документа | тема · источник темы · процессный | `canon/references/canon.md` |
|
||||
| severity находки | `critical` `major` `minor` `nit` | `code-review/references/finding-contract.md` |
|
||||
| коды выхода | 0 1 2 3 4 | здесь, ниже |
|
||||
@@ -39,39 +52,41 @@
|
||||
| --- | --- | --- |
|
||||
| стадия проекта | что значит порядок строк беклога: зависимость или важность | `task-track/SKILL.md`, «Две стадии» |
|
||||
| стадия проекта | сколько у беклога секций, как его пополняют, применим ли груминг | там же и `task-groom/SKILL.md`, «Груминг — операция доработки» |
|
||||
| стадия проекта | метку и глубину — **не влияет, и это записано явно** | `task-track/SKILL.md`, «Тип записи» |
|
||||
| стадия проекта | глубину ревью — **не влияет, и это записано явно** | `task-track/SKILL.md`, «Тип записи» |
|
||||
| стадия проекта | тип записи — **не влияет, и это записано явно** | `task-track/SKILL.md`, «Две стадии» |
|
||||
| стадия проекта | как серьёзность находки ложится в список | `task-track/references/from-review.md` |
|
||||
| стадия проекта | где сценарии кладут свой исход и чем закрывают переходное состояние | `code-resolve/references/research.md`, `task-track/references/adopt.md` |
|
||||
| форма постановки | проверку готовности, кто называет тип, есть ли шаг закрытия | `code-resolve/SKILL.md`, «Постановка текстом» |
|
||||
| форма постановки | сценарий, метку и глубину — **не влияет, и это записано явно** | там же: развилка у обеих форм общая |
|
||||
| форма постановки | сценарий и глубину ревью — **не влияет, и это записано явно** | там же: развилка у обеих форм общая |
|
||||
| тип записи | сценарий — **предлагает**, подтверждает предмет работы | `task-track/SKILL.md`, «Тип записи» |
|
||||
| тип записи | метку и глубину — **не влияет, и это записано явно** | там же |
|
||||
| сценарий | режим прогона: обслуживание идёт без метки | `code-resolve/references/maintain.md` |
|
||||
| метка | состав проходов обеих стадий | `code-review/SKILL.md`, «Метки» |
|
||||
| метка | глубину темы: против чего смотрят и как | там же |
|
||||
| тип записи | глубину ревью — **не влияет, и это записано явно** | там же |
|
||||
| сценарий | режим прогона: обслуживание идёт без change | `code-resolve/references/maintain.md` |
|
||||
| режим прогона | состав проходов и саму возможность запуска прохода | `code-review/SKILL.md`, «Прогон без change» |
|
||||
| категория документа | заводит ли документ направление проверки | `canon.md`, «Три категории» |
|
||||
| severity | что с находкой делают дальше | `code-review/SKILL.md`, «Что происходит с находками» |
|
||||
| род правки | спрашивают ли человека перед письмом в документ | `doc-sync/SKILL.md`, «Два рода правок» |
|
||||
| глубина темы | что проход делает с домом темы и какой потолок у находок | `code-review/SKILL.md`, таблица тем |
|
||||
| разметка действия | чинится находка молча или уходит человеку вопросом | `code-review/SKILL.md`, «Что происходит с находками» |
|
||||
| разметка действия | возвращается ли прогон на чекпоинт — **не задаёт**: возврат старше развилки и решается признаком «меняются ли дельта-спеки» | `code-resolve/references/solve.md`, шаг 5 |
|
||||
| сценарий | какова доля отражения в синке: обслуживание двигает факты и потому спрашивает редко | `code-resolve/references/maintain.md`, шаг 5 |
|
||||
|
||||
**Пять клеток пусты, и это сказано намеренно, а не забыто.**
|
||||
**Четыре клетки пусты, и это сказано намеренно, а не забыто.**
|
||||
|
||||
**Категория документа × режим прогона.** На прогоне **с меткой** своя тема
|
||||
проекта закрыта при любом значении: `review-basics` — приёмник проектных тем и
|
||||
при `small`, и при `large`, и при `medium`. На прогоне **без метки** план
|
||||
фиксирован сценарием — `autotests`, `operations`, `conventions`, — и своих тем
|
||||
проекта в нём нет. Значит, документ, заведённый проектом как тема, на
|
||||
обслуживании не смотрит никто, и строкой это нигде не называется.
|
||||
**Категория документа × режим прогона.** На прогоне **по change** своя тема
|
||||
проекта закрыта: `review-basics` — её приёмник, и запускается он тогда и только
|
||||
тогда, когда такие темы у проекта есть. На прогоне **без change** план фиксирован
|
||||
сценарием — `autotests`, `operations`, `conventions`, — и своих тем проекта в нём
|
||||
нет. Значит, документ, заведённый проектом как тема, на обслуживании не смотрит
|
||||
никто, и строкой это нигде не называется.
|
||||
|
||||
**Стадия проекта × метка.** Изменение на стройке ничем не проще того же
|
||||
изменения на доработке: метку назначает разметка по факту изменения, и стадия в
|
||||
неё не входит. Заманчивая мысль «на стройке всё `small`, потому что приложения
|
||||
ещё нет» разбивается о первый же шаг, кладущий схему хранилища.
|
||||
**Род правки × severity и × режим прогона.** Не влияет ни туда, ни обратно: род
|
||||
правки — свойство того, что пишется в документ, и с находкой ревью он не
|
||||
встречается. Находка, доехавшая до конвенции, меняет род не сама по себе, а тем,
|
||||
что становится новой нормой, — и спрашивается тогда как всякое новое.
|
||||
|
||||
**Стадия проекта × режим прогона и × стадия ревью.** Не влияет ни на одну:
|
||||
режим выбирает сценарий, стадию ревью — наличие дизайна. Прогон обслуживания на
|
||||
стройке — обычное дело (первые шаги плана заводят гейт и сборку), и идёт он там
|
||||
так же, как на доработке.
|
||||
**Стадия проекта × режим прогона.** Не влияет: режим выбирает сценарий. Прогон
|
||||
обслуживания на стройке — обычное дело (первые шаги плана заводят гейт и сборку),
|
||||
и идёт он там так же, как на доработке.
|
||||
|
||||
**Стадия проекта × категория документа, × коды выхода и × форма постановки.** Не
|
||||
влияет: категория — свойство документа, коды — общий словарь скриптов, а форму
|
||||
@@ -79,10 +94,11 @@
|
||||
доработке. Названо потому, что перечень объявлен полным, и клетка без ответа
|
||||
читается как забытая.
|
||||
|
||||
**Режим прогона × severity.** Триаж обязателен всегда, в том числе без метки. Но
|
||||
часть оснований `critical` — построенный путь к отказу, замер — добывается
|
||||
проходами, которые без метки не запускаются. Значит ли это, что `critical` на
|
||||
прогоне обслуживания не бывает, или что его основания там другие, не сказано.
|
||||
**Режим прогона × severity.** Триаж обязателен всегда, в том числе без change. Но
|
||||
часть оснований `critical` — построенный путь к отказу, замер — добывается только
|
||||
скиллом `av-dev:code-deep-review`, а в цикле задачи не добывается ни на одном
|
||||
прогоне. Значит ли это, что `critical` там не бывает вовсе, или что его основания
|
||||
другие, не сказано.
|
||||
|
||||
## Режим прогона
|
||||
|
||||
@@ -90,19 +106,19 @@
|
||||
|
||||
**Прогон ревью идёт в одном из двух режимов, и режим — не глубина.**
|
||||
|
||||
- **С меткой** — обычный прогон по change: разметку сделал `review-scope`, состав
|
||||
обеих стадий выведен из метки.
|
||||
- **Без метки** — прогон сценария обслуживания: change нет, размечать нечего,
|
||||
план фиксирован и назван сценарием. Разметчик не запускается вовсе.
|
||||
- **По change** — обычный прогон цикла задачи: есть дифф и дельта-спеки, состав
|
||||
постоянный и живёт в конвейере.
|
||||
- **Без change** — дельта-спек нет по построению, и вместе с ними нет темы
|
||||
`requirements`. План фиксирован и назван вызывающим; так идёт сценарий
|
||||
обслуживания.
|
||||
|
||||
**Без метки — не то же самое, что `small`.** `small` — это суждение о размере и
|
||||
сложности, снятое с изменения; отсутствие метки — утверждение, что снимать её
|
||||
не с чего. Проход, подставивший себе `small` там, где метки нет, вывел бы
|
||||
глубину из ничего.
|
||||
**Режим правит состав, а не глубину.** Глубина темы стоит в таблице тем
|
||||
конвейера, одна на все прогоны по change; на прогоне без change её называет план
|
||||
сценария — иначе проход, чьей темы в плане нет, взял бы глубину наугад.
|
||||
|
||||
**Режим правит не только состав, но и саму возможность запуска.** Проход, у
|
||||
которого запуск задан меткой, без метки не имеет ответа на вопрос «запускаться
|
||||
ли» — и ответ ему даёт план сценария, а не умолчание.
|
||||
**Третьего режима у конвейера нет.** Скилл `av-dev:code-deep-review` конвейер не
|
||||
зовёт вовсе: состав, глубина и вход у него свои, а общее с конвейером — уставы
|
||||
проходов и контракт находок.
|
||||
|
||||
<!-- /дом: режим-прогона -->
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ LEGACY_TASKS = ".tasks.json"
|
||||
|
||||
# Версия раскладки — одна на плагин. Журнал версий — references/changelog.md
|
||||
# скилла `canon`, повышает его операция `upgrade`.
|
||||
VERSION = 4
|
||||
VERSION = 5
|
||||
|
||||
VERSION_KEY = "version"
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ openspec/
|
||||
Раньше здесь стояло плоское правило «каждый документ `docs/` — тема ревью». Оно
|
||||
неверно ровно наполовину: паспорт и схема хранилища ревью нужны, но темами не
|
||||
являются, а журнал решений и журнал наблюдений ревью изменения не нужны вовсе.
|
||||
Плоское правило заставляло разметчика либо плодить фантомные темы, либо терять
|
||||
Плоское правило заставляло прогон либо плодить фантомные темы, либо терять
|
||||
документы молча — а молчащая потеря и есть то, против чего канон написан.
|
||||
|
||||
**Разрез один и проверяемый: можно ли по документу сказать «в этом изменении
|
||||
@@ -167,19 +167,17 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
Одна строка на каждый — на какой вопрос он отвечает, в какой он категории и
|
||||
какую тему питает. **Кто именно закрывает тему, здесь не указано намеренно**: это
|
||||
зависит от метки прогона и меняется вместе с конвейером, а документ живёт
|
||||
дольше. Раскладку «тема → проход → глубина» держит скилл
|
||||
`av-dev:code-review`.
|
||||
меняется вместе с конвейером, а документ живёт дольше. Раскладку «тема → кто
|
||||
закрывает → против чего» держит скилл `av-dev:code-review`.
|
||||
|
||||
**Общего словаря у канона с конвейером ровно три вида имён: имена категорий,
|
||||
имена тем и имена меток.** Категорий три — `тема`, `источник`, `процессный`;
|
||||
**меток тоже три, и они закрыты: `small`, `medium`, `large`.** Метка это итог
|
||||
классификации задачи, и по ней конвейер выбирает исполнителей на обеих стадиях
|
||||
ревью; проект её не выдумывает, а только уточняет триггеры. Ими проект и
|
||||
настраивает ревью — вопросами по темам и триггерами метки. **Имён проходов канон не называет нигде**, включая вывод `docs.py`:
|
||||
проход переименовывается и переезжает между метками, и канон, назвавший его, в
|
||||
этот день соврёт молча. Обратное направление законно — конвейер называет
|
||||
документы канона поимённо, потому что он их читатель.
|
||||
**Общего словаря у канона с конвейером два вида имён: имена категорий и имена
|
||||
тем.** Категорий три — `тема`, `источник`, `процессный`; список тем открытый, и
|
||||
пополняет его сам проект своим документом. Настраивает проект ревью двумя вещами:
|
||||
вопросами по темам и признаками, по которым зовут глубокое ревью. **Имён проходов
|
||||
канон не называет нигде**, включая вывод `docs.py`: проход переименовывается и
|
||||
переезжает в другой скилл, и канон, назвавший его, в этот день соврёт молча.
|
||||
Обратное направление законно — конвейер называет документы канона поимённо,
|
||||
потому что он их читатель.
|
||||
|
||||
| Документ | Вопрос | Категория и тема |
|
||||
| --- | --- | --- |
|
||||
@@ -297,6 +295,11 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
«заменено на».
|
||||
<!-- /дом: adr-когда-заводить -->
|
||||
|
||||
**Сработавший триггер даёт предложение, а не запись.** Заводит ADR человек своим
|
||||
словом — правило и его причина в скилле `av-dev:doc-sync`, раздел «Два рода
|
||||
правок». Канон здесь отвечает за другое: за то, при каких условиях предлагать
|
||||
вообще есть что.
|
||||
|
||||
Не заводится для рутины и для того, что видно из кода и `git log`.
|
||||
|
||||
Записи неизменяемы: передумали — заводится новая, старая получает статус.
|
||||
@@ -319,29 +322,30 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
- **Типовые ложноположительные** — находки, которые здесь выглядят убедительно и
|
||||
всегда неверны, каждая со строкой «почему здесь это не дефект»;
|
||||
- **Вопросы по темам** — в форме `<тема>: <вопрос> (<откуда>)`. **Не по именам
|
||||
проходов**: проход уезжает между метками, а тема остаётся, и вопрос,
|
||||
адресованный проходу, перестал бы задаваться молча в тот день, когда тот уехал
|
||||
в старшую метку. Задаёт вопрос тот, кто закрывает тему на этом прогоне.
|
||||
проходов**: проход уезжает в другой скилл, а тема остаётся, и вопрос,
|
||||
адресованный проходу, перестал бы задаваться молча в тот день, когда тот уехал.
|
||||
Задаёт вопрос тот, кто закрывает тему на этом прогоне.
|
||||
Адресовать можно только теме: `passport`, `database`, `adr`, `research` и
|
||||
`review` — не темы, и вопрос, адресованный им, не задаст никто;
|
||||
- **Триггеры метки** — проектная конкретизация правила выбора метки ревью,
|
||||
**тремя списками**. Два поднимают, по одному на ось: что в этом проекте считается
|
||||
**крупным** (объём: сколько узлов и слоёв трогает) и что считается
|
||||
**незнакомым** (форма решения: известна до начала или нащупывается по ходу).
|
||||
Любая из двух осей поднимает прогон до `large`, старшей метки, — а она
|
||||
рассчитана на 5–10% задач. Третий список — что считается **мелким** (опускает
|
||||
до `small`); он один, потому что вниз метку опускает только совпадение обеих
|
||||
осей сразу. Перечнем мест, узлами или capability, а не вторым определением
|
||||
класса. Уточняет умолчания, а не отменяет их. Рабочее умолчание — `medium`:
|
||||
миграция схемы и публичный контракт метку **не** поднимают, их проверяют
|
||||
проходы, которые в `medium` и так есть;
|
||||
- **Когда звать глубокое ревью** — проектная конкретизация признаков, по которым
|
||||
зовут `av-dev:code-deep-review`, **двумя списками**: области, которые смотрят
|
||||
целиком (узлы с частым возвратом, места с историей инцидентов, код под дорогое
|
||||
решение), и **необратимое здесь** — что в этом проекте после мерджа не
|
||||
откатывается обратной правкой. Второй список работает и в цикле задачи: находка
|
||||
в таком месте уходит человеку развилкой, а не чинится молча. Перечнем мест,
|
||||
узлами или capability, а не вторым определением класса;
|
||||
- **Недоступно проверке** — два подраздела, оба **по темам**: «не проверит ни
|
||||
один проход» (принципиальная граница, по факту промаха не пересматривается) и
|
||||
«перестали проверять сознательно» (пересматривается первым). Тема, у которой в
|
||||
проекте нет дома, сюда не пишется: её и так называет план каждого прогона.
|
||||
|
||||
**Журнал дефектов:** запись на каждый воспроизведённый дефект с пометкой
|
||||
**проскочил / пойман ревью**. Проскочившие — проверочный набор для калибровки конвейера,
|
||||
**проскочил / пойман ревью**. Запись — новое, и заводится она по слову человека
|
||||
(`av-dev:doc-sync`, «Два рода правок»): «на каждый» задаёт **обязанность
|
||||
предложить**, а не право записать молча. Человек отказал — записи нет, и
|
||||
калибровка конвейера по этому дефекту не состоится; это его решение и его цена.
|
||||
|
||||
Проскочившие — проверочный набор для калибровки конвейера,
|
||||
выборка по пометке. Пойманные с оракулом — лучшая опора для прохода: проектные,
|
||||
воспроизводимые, однажды оказавшиеся правдой.
|
||||
|
||||
@@ -427,7 +431,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
**Файл канону не принадлежит, и проверяет его тоже не канон.** Каталог
|
||||
`openspec/` — предпосылка конвейера: без него не работают ни `opsx:propose`, ни
|
||||
ревью дизайна, ни сверка требований. Заводит его, настраивает и **проверяет
|
||||
сверка требований. Заводит его, настраивает и **проверяет
|
||||
форму** скилл `av-dev:code-openspec`: там образец файла, там же скрипт
|
||||
`openspec.py check`. `docs.py` о файле не говорит ничего.
|
||||
|
||||
@@ -556,6 +560,7 @@ version = 1 # версия раскладки
|
||||
|
||||
[docs]
|
||||
migrations = "internal/store/migrations" # если БД есть
|
||||
healthcheck_last = "a1b2c3d" # сверка документов: коммит прошлого прогона
|
||||
|
||||
[tasks]
|
||||
dir = "tasks" # каталог задач от корня репозитория
|
||||
@@ -569,6 +574,18 @@ dir = "tasks" # каталог задач от корн
|
||||
делает сверку с `database.md`. `[tasks]` — где лежит каталог задач и как названы
|
||||
его части; состав ключей описывает скилл `task-track`.
|
||||
|
||||
`[docs] healthcheck_last` — коммит, на котором в последний раз проходила сверка
|
||||
документов; ставит его сам `av-dev:doc-healthcheck` последним шагом прогона, а
|
||||
читает `av-dev:doc-sync`, чтобы сосчитать задачи, сделанные с тех пор. **Ключ
|
||||
необязательный и в скелете его нет намеренно**: у нового проекта сверок не было,
|
||||
и пустое значение врало бы про это меньше, чем отсутствие ключа, только на вид.
|
||||
Отсутствие читается однозначно — «не сверялись ни разу».
|
||||
|
||||
Секции он достался по смыслу: `[docs]` — настройки проверок документов, а сверка
|
||||
документов и есть такая проверка. Своя секция верхнего уровня стоила бы правки
|
||||
общего читателя `shared/config.py` и сделала бы файл, объявленный «версией и
|
||||
настройками», хранилищем состояния.
|
||||
|
||||
**Формат TOML взят ради комментариев.** Файл лежит в репозитории проекта, и
|
||||
человек, открывший его через полгода, обязан прочитать в нём, что означает
|
||||
число. JSON комментариев не знает, и объяснение приходилось держать в другом
|
||||
@@ -583,6 +600,20 @@ dir = "tasks" # каталог задач от корн
|
||||
читаются: два дома для одной версии расходятся молча. Увидев их, `docs.py` и
|
||||
`tasks.py` говорят «прежняя раскладка» и зовут `upgrade` — версия 1 журнала.
|
||||
|
||||
Ключей будет больше по мере роста проверок; неизвестный ключ `docs.py`
|
||||
игнорирует, отсутствующий — считает «проверка неприменима» и говорит об этом
|
||||
строкой, а не молчит.
|
||||
Ключей будет больше по мере роста проверок, но **заводятся они только вместе с
|
||||
правкой скрипта**: неизвестный ключ — не безмолвный пропуск, а **отказ кодом
|
||||
3**. Верхний уровень стережёт `shared/config.py` (`TOP_KEYS`), секцию `[docs]` —
|
||||
`docs.py` (`DOCS_KEYS`), секцию `[tasks]` — `tasks.py`. Довод у отказа
|
||||
проверяемый: ключ, положенный не в ту секцию, при молчаливом пропуске не значит
|
||||
ничего — проверка объявляет себя неприменимой, отчёт выходит зелёным, и на месте
|
||||
настройки оказывается тишина.
|
||||
|
||||
**Здесь это правило однажды соврало, и цена была немедленной.** Абзац обещал, что
|
||||
неизвестный ключ игнорируется; по этому обещанию скилл сверки завёл себе секцию
|
||||
`[healthcheck]` верхнего уровня — и первый же её прогон сделал бы нерабочими
|
||||
`docs.py`, `tasks.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` — закомментированный пример на английском. Такой файл
|
||||
|
||||
@@ -22,6 +22,44 @@
|
||||
|
||||
---
|
||||
|
||||
## Версия 5 — 2026-08-23
|
||||
|
||||
**Метка задачи снята из процесса целиком**, и вместе с ней — подраздел «Триггеры
|
||||
метки» в `docs/review.md`. Состав прогона ревью стал постоянным: он один и тот же
|
||||
на всякой задаче, выбирать нечего, и признаки, по которым метка поднималась,
|
||||
перестали что-либо решать. На месте подраздела — **«Когда звать глубокое ревью»**:
|
||||
те же наблюдения проекта, но адресованные другому решению — звать ли
|
||||
`av-dev:code-deep-review` по области кода.
|
||||
|
||||
**Что переехало в проекте.** Скелет `docs/review.md`, раздел настройки конвейера:
|
||||
подраздел «Триггеры метки» заменён подразделом «Когда звать глубокое ревью» —
|
||||
**двумя списками**: области, которые смотрят целиком (узлы с частым возвратом,
|
||||
места с историей инцидентов, код под дорогое решение), и **необратимое здесь** —
|
||||
что в этом проекте после мерджа не откатывается обратной правкой. Второй список
|
||||
работает и в цикле задачи: находка в таком месте уходит человеку развилкой, а не
|
||||
чинится молча. Само правило — в [canon.md](canon.md), раздел `review.md`.
|
||||
|
||||
**Что сделать проекту.**
|
||||
|
||||
1. **Переписать подраздел в `docs/review.md`.** Заголовок «Триггеры метки»
|
||||
становится «Когда звать глубокое ревью», содержимое — два списка выше.
|
||||
Признаки, годные только для выбора метки («больше N файлов», «затронуто больше
|
||||
одного слоя»), выбрасываются: состава прогона они не меняют. Что из прежнего
|
||||
списка называло **необратимое место** — переносится во второй список дословно.
|
||||
2. **Пройти по документам** — `grep -rniE "small|medium|large|метк" docs/`.
|
||||
Найденное в `review.md`, `conventions/` и `adr/` правится по смыслу: описание
|
||||
прошлого решения остаётся как свидетельство, действующая инструкция —
|
||||
переписывается или снимается.
|
||||
3. **Поднять версию** — `docs.py bump`, последним шагом.
|
||||
4. `docs.py check` — до отсутствия дрейфа.
|
||||
|
||||
**Чего делать не надо.** Заводить ключ `[docs] healthcheck_last` руками: он
|
||||
необязательный и появится сам первым прогоном `av-dev:doc-healthcheck`. Править
|
||||
прошлые записи журналов и архивные change — тоже: метка, стоявшая в них, верна
|
||||
как свидетельство о том дне.
|
||||
|
||||
---
|
||||
|
||||
## Версия 4 — 2026-08-13
|
||||
|
||||
Слово **провенанс** снято из словаря языка проектных текстов и заменено русским.
|
||||
|
||||
@@ -287,10 +287,9 @@
|
||||
задаёт тот проход, который закрывает эту тему на текущем прогоне, дополнительно
|
||||
к обязательным.
|
||||
|
||||
**Адресуй теме, а не имени прохода.** Проходы переезжают между метками и
|
||||
**Адресуй теме, а не имени прохода.** Проходы переезжают между скиллами и
|
||||
упраздняются; вопрос, адресованный проходу, перестанет задаваться в тот день,
|
||||
когда тот уедет в старшую метку, — и заметить это будет нечем. Тема переезд
|
||||
переживает.
|
||||
когда тот уедет, — и заметить это будет нечем. Тема переезд переживает.
|
||||
|
||||
Темы ядра: `requirements`, `autotests`, `conventions`, `architecture`,
|
||||
`security`, `operations`. Плюс любая своя — та, под которую проект завёл в
|
||||
@@ -299,30 +298,22 @@
|
||||
`review` нельзя — таких тем нет. Вопрос про границу домена адресуй
|
||||
`architecture`, вопрос про хранилище и числа — `operations`.
|
||||
|
||||
### Триггеры метки
|
||||
### Когда звать глубокое ревью
|
||||
|
||||
Проектная конкретизация правила выбора метки. **Списка три: по одному на
|
||||
каждую ось вверх и один вниз** — поимённо, узлами или capability.
|
||||
Проектная конкретизация признаков, по которым зовут `av-dev:code-deep-review`.
|
||||
**Списка два, оба поимённо — узлами, слоями или capability.**
|
||||
|
||||
**Крупное здесь** — про объём: что трогает несколько узлов или слоёв, переносит
|
||||
ответственность между ними, перекладывает существующий код в новую форму.
|
||||
**Области, которые смотрят целиком:** узлы, куда задачи возвращаются чаще
|
||||
прочих, места с историей инцидентов, код, на который обопрётся дорогое решение.
|
||||
|
||||
**Незнакомое здесь** — про форму решения: то, чего в проекте ещё не было и чью
|
||||
форму предстоит нащупать по ходу. Признак простой: перед работой нельзя назвать,
|
||||
какие узлы будут тронуты.
|
||||
**Необратимое здесь:** что в этом проекте после мерджа не откатывается обратной
|
||||
правкой — миграции, формат на диске, публичный контракт, имена, расходящиеся по
|
||||
базе. Находка в таком месте уходит человеку развилкой, а не чинится молча, и
|
||||
список нужен затем, чтобы «необратимое» не решалось на глаз.
|
||||
|
||||
Любая из двух осей поднимает прогон до `large`, старшей метки: там `security`,
|
||||
`operations` и `architecture` проверяют запуском, и там же единственные замеры.
|
||||
Метка рассчитана на **5–10% задач**; если сюда попадает каждая третья, списки
|
||||
написаны слишком широко.
|
||||
|
||||
**Мелкое здесь** — опускает до `small`. Ориентир по доле — до трети задач, и в
|
||||
любом случае меньше, чем `medium`: перевес `small` значит, что рабочее умолчание
|
||||
сместилось само. Помни отрицательный тест конвейера: что
|
||||
после мерджа не откатывается обратной правкой (миграция, формат на диске,
|
||||
публичный контракт, имя), — не `small`, каким бы маленьким ни был дифф.
|
||||
|
||||
Уточняет умолчания конвейера, не отменяет их; рабочее умолчание — `medium`.
|
||||
Цикл задачи проверяет корректность и механику одним и тем же составом; глубину
|
||||
даёт только отдельный прогон по области, и **зовёт его человек**. Списки уточняют
|
||||
признаки, а не заводят расписание.
|
||||
|
||||
### Недоступно проверке
|
||||
|
||||
|
||||
@@ -296,7 +296,15 @@ def read_config(root: Path, rep: Report) -> dict:
|
||||
|
||||
# Ключи секции `[docs]`. Секцию знает этот скрипт, а не общий читатель: ключ
|
||||
# заводится вместе с проверкой, которая его читает.
|
||||
DOCS_KEYS = ("migrations",)
|
||||
#
|
||||
# `healthcheck_last` — коммит прошлой сверки документов; пишет его скилл
|
||||
# `av-dev:doc-healthcheck`, читает `av-dev:doc-sync`, чтобы сосчитать задачи с
|
||||
# тех пор. Здесь он стоит **только чтобы файл не отвергли**: неизвестный ключ —
|
||||
# отказ кодом 3, то есть ключ, заведённый скиллом мимо этой константы, сделал бы
|
||||
# нерабочими и `docs.py`, и `tasks.py`, и гейт проекта, который их зовёт.
|
||||
# Проверки, читающей его, у скрипта нет и не предполагается: значение — след
|
||||
# работы человека, а не настройка.
|
||||
DOCS_KEYS = ("migrations", "healthcheck_last")
|
||||
|
||||
|
||||
def docs_cfg(cfg: dict) -> dict:
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
---
|
||||
name: code-deep-review
|
||||
description: "Глубокое ревью области кода — не задачи, а куска проекта: модуля, слоя, сервиса целиком. Зовёт проходы, которых нет в цикле задачи: review-adversary (строит путь и прогоняет падающий тест), review-ops (снимает числа замером), review-architecture на входе шире диффа и по форме решения, review-code по коду целиком, а сводит их review-triage. Здесь единственное место процесса, где форму решения судят после кода и где находка доказывается прогоном и замером. Проходы, помеченные «держит машину», идут цепочкой. Исход — не правки, а разговор: находки предлагаются человеку, обсуждаются по одной, и согласованное уезжает задачами через av-dev:task-track, сценарий «задачи из ревью и аудита». Использовать время от времени и по признаку: накопился десяток задач в одной области, перед тем как опереться на узел в дорогом решении, после инцидента, по строке «отложено в code-deep-review» из отчётов ревью. Дорого — не на задаче и не по расписанию. Ревью одного изменения — скилл av-dev:code-review."
|
||||
---
|
||||
|
||||
# Глубокое ревью области
|
||||
|
||||
Смотрит **не задачу, а место в проекте**: модуль, слой, сервис целиком. Отсюда и
|
||||
всё остальное устройство — вход, состав проходов, исход.
|
||||
|
||||
Разрез с конвейером задачи проверяемый: **`av-dev:code-review` судит изменение,
|
||||
этот скилл судит написанное**. Там вход — дифф и дельта-спеки, здесь — область
|
||||
кода и её история. Там исход — правки в том же прогоне, здесь — разговор и
|
||||
задачи.
|
||||
|
||||
## Зачем он появился
|
||||
|
||||
Тяжёлые проходы стояли в цикле задачи: `review-adversary` строил путь и прогонял
|
||||
падающий тест, `review-ops` снимал числа замером, `review-architecture` судил
|
||||
форму решения на входе шире диффа. Первые двое держали машину и шли цепочкой,
|
||||
третий требовал карты проекта; все трое стоили часов **на каждой задаче**, где
|
||||
запускались, — при том что их ценность оплачивается на каждой, а получается на
|
||||
немногих.
|
||||
|
||||
Их вынесли сюда целиком, и цикл задачи после этого проверяет **корректность и
|
||||
механику**: заказанное против сделанного, дефект, который сработает сам,
|
||||
конвенции проекта и сверку с записанными инвариантами `CLAUDE.md`. Темы
|
||||
`security`, `operations` и `architecture` остались там ровно в объёме
|
||||
инвариантов — свойства, которого в них нет, цикл не спросит.
|
||||
|
||||
**Вход этому скиллу копят проходы цикла.** Строка «отложено в
|
||||
`av-dev:code-deep-review`» в границах покрытия называет тему, место и запуск,
|
||||
которым это проверяется; триаж сводит такие строки в отдельную секцию отчёта.
|
||||
Второй источник — сигнал «это изменение просит глубокого ревью»: его подаёт
|
||||
`review-code` всегда и `review-basics`, когда запускается.
|
||||
|
||||
## Когда звать
|
||||
|
||||
**Зовёт человек**, и признак наблюдаемый, а не календарный:
|
||||
|
||||
- **накопился десяток задач в одной области** — по отдельности каждая прошла
|
||||
обычный цикл, а вместе они переписали узел;
|
||||
- **строки «отложено» скопились**: в отчётах ревью по одному месту повторяется
|
||||
один и тот же неснятый замер;
|
||||
- **перед дорогим решением**, которое обопрётся на этот узел;
|
||||
- **после инцидента** — когда уже известно, где болит, и надо понять, что рядом;
|
||||
- **узел, в который возвращаются третий раз**: цикл задачи проверяет его каждый
|
||||
раз заново и одним и тем же составом, а здесь это повод посмотреть узел целиком.
|
||||
|
||||
**Не на задаче и не по расписанию.** Цена реальная: два прохода держат машину и
|
||||
идут цепочкой, вход шире диффа собирается командой проекта, а разбор находок
|
||||
требует человека. Прогон по каждой задаче был бы ровно той церемонией, ради
|
||||
снятия которой проходы отсюда и переехали.
|
||||
|
||||
## Чего может не быть
|
||||
|
||||
**Копия.** Дом правила — `shared/absence.md` в репозитории плагина.
|
||||
Правится дом, а не этот файл.
|
||||
|
||||
<!-- копия: отсутствие из av-dev/shared/absence.md -->
|
||||
|
||||
**Скилл не вправе считать раскладку проекта полной.** Части заводятся порознь и
|
||||
живут порознь; каждая узнаётся своим следом:
|
||||
|
||||
| Чего нет | Как видно | Чего теперь не делает никто |
|
||||
| --- | --- | --- |
|
||||
| настройки av-dev | нет `.av-dev.toml` в корне | проект под процесс не заводился; версии нет, настроек нет |
|
||||
| документы канона | нет `docs/` | проектную конкретику брать неоткуда — темы, инварианты, прецеденты |
|
||||
| учёт работ | нет каталога задач | запись остаётся владельцу: назови её текстом в докладе |
|
||||
| источник требований | нет `openspec/config.yaml` | цикл SDD не запускается: спеки не с чем сверять |
|
||||
|
||||
**Свой скилл зовётся полным именем** — `av-dev:canon`, `av-dev:task-track`,
|
||||
`av-dev:code-review`. Короткое имя может разрешиться в устаревшую проектную
|
||||
копию из `.claude/skills/`, и подмены не будет видно ни в докладе, ни в
|
||||
поведении.
|
||||
|
||||
**Внешний плагин может не стоять.** Их два: `opsx:*` — цикл SDD, и
|
||||
`av-dev-git:commit` — сообщения коммитов. Путь в дерево чужого плагина не
|
||||
пишется никогда: `$CLAUDE_PLUGIN_ROOT` ведёт только в своё дерево, а
|
||||
вычисленный от него путь к соседу либо не откроется, либо откроет чужую
|
||||
установку. Нужен чужой справочник — зови владеющий им скилл, он прочитает его
|
||||
сам.
|
||||
|
||||
**Отсутствие — исход, а не поломка.** Назови строкой доклада, чего теперь не
|
||||
делает никто, и продолжай работу. Молчать нельзя: пропуск неотличим от
|
||||
сделанного. Выдумывать обходной путь нельзя тоже.
|
||||
|
||||
**Присутствие узнаётся следом в проекте, а не объявлением.** Перечня того, что
|
||||
здесь заведено, проект не ведёт — он разошёлся бы с действительностью молча.
|
||||
|
||||
<!-- /копия: отсутствие -->
|
||||
|
||||
**Каталога задач нет** — находки остаются списком в докладе, и это говорится
|
||||
строкой: заводить их некуда, а держать в голове до следующего прогона нечем.
|
||||
|
||||
## Вход — область, а не дифф
|
||||
|
||||
**Область называет человек, и называет до запуска.** Пакет, слой, сервис,
|
||||
capability — одним адресом или несколькими. Скилл область не выбирает сам: выбор
|
||||
области и есть решение о том, во что вложить часы, и оно человеческое.
|
||||
|
||||
Область не названа — **спроси, а не бери репозиторий целиком**. Прогон по всему
|
||||
проекту даёт находки, рассыпанные по местам, между которыми нет связи, а разбор
|
||||
такого урожая не доводится до конца никогда.
|
||||
|
||||
К области собирается **корпус**:
|
||||
|
||||
| Что | Откуда | Зачем |
|
||||
|---|---|---|
|
||||
| код области целиком | адреса, названные человеком | вход всех проходов |
|
||||
| история области | `git log` по этим путям | что переписывалось и сколько раз |
|
||||
| отложенное | строки «отложено в `av-dev:code-deep-review`» из отчётов ревью | неснятые замеры и недостроенные пути |
|
||||
| журнал дефектов | `docs/review.md` | что уже проскакивало мимо конвейера |
|
||||
| дома тем | `docs/security.*`, `docs/architecture.*`, `docs/conventions.*` | против чего судить |
|
||||
|
||||
Отложенного нет вовсе — скажи это строкой. Пустой список значит либо что цикл
|
||||
ничего не откладывал, либо что проходы не писали свою строку; вторая причина —
|
||||
находка о процессе, и она идёт в доклад.
|
||||
|
||||
## Состав прогона
|
||||
|
||||
Состав **постоянный**, но глубина у проходов **разная, и это не небрежность**.
|
||||
Доказательство дают те двое, что держат машину: `review-adversary` прогоняет
|
||||
падающий тест, `review-ops` снимает числа замером. `review-architecture` и
|
||||
`review-code` машину не держат — они дают **разбор на входе шире диффа**, и
|
||||
выдать доказательство им нечем. Постоянен и состав цикла задачи, но он другой и
|
||||
мельче: разница между скиллами не в старательности, а в том, что здесь запускают,
|
||||
меряют и строят путь.
|
||||
|
||||
| Проход | Тема | Что делает |
|
||||
|---|---|---|
|
||||
| `review-adversary` | `security` | строит путь и **прогоняет** падающий тест |
|
||||
| `review-ops` | `operations` | снимает числа замером: удержание, рост, деградация |
|
||||
| `review-architecture` | `architecture` | концептуальная целостность на входе шире диффа |
|
||||
| `review-code` | `conventions`, техника, инварианты | читает код **как код**, целиком, а не диффом; потолков здесь нет |
|
||||
| `review-triage` | — | единственный сток: дедуп, оракулы, потолок |
|
||||
|
||||
**Гейта здесь нет, и это не пропуск.** Гейт судит изменение — красный он или
|
||||
зелёный, к написанному месяц назад коду это не относится. Если гейт проекта
|
||||
красный, скажи это строкой: находки о коде, который не собирается, стоят меньше.
|
||||
|
||||
**Цепочка за машину остаётся.** `review-adversary` и `review-ops` помечены
|
||||
«держит машину» и идут друг за другом, а не разом: два прохода на одной машине
|
||||
выдают числа, которые не воспроизведутся. Правило и его причина — дом в
|
||||
`av-dev:code-review`, раздел «Кто держит машину». Здесь эта цена приемлема:
|
||||
скилл идёт не на задаче, и часы у него есть.
|
||||
|
||||
`review-architecture` и `review-code` машину не держат — уходят первой волной,
|
||||
разом.
|
||||
|
||||
**Задание каждому проходу собирается адресами**: область, дома его тем, контракт
|
||||
находок, отложенные строки по его теме и признак «вход — область, а не дифф».
|
||||
Проход, получивший привычное «суди дифф», сузит себя сам.
|
||||
|
||||
## Триаж — тот же, вход другой
|
||||
|
||||
`review-triage` сводит выводы всех проходов: дедуп по причине, оракул на всё
|
||||
`critical` и `major`, понижение неподтверждённого до гипотезы, отсев вкусовщины,
|
||||
ранжирование по ущербу × вероятности.
|
||||
|
||||
**Потолка в 7 пунктов здесь нет.** Он существует потому, что отчёт по задаче
|
||||
читает тот, кто **молча реализует** прочитанное, и длинный список превращается в
|
||||
разросшийся код. Здесь читатель — человек, и каждый пункт он разбирает вслух.
|
||||
Вместо потолка — **порядок**: находки идут по убыванию ущерба, и разговор
|
||||
начинается сверху.
|
||||
|
||||
План прогона триажу передаётся составом: перечень проходов и тем. Тема, не
|
||||
вернувшая отчёта, называется в границах покрытия — правило то же, что в конвейере
|
||||
задачи.
|
||||
|
||||
## Разбор с человеком — главный шаг
|
||||
|
||||
**Исход этого скилла — не правки, а согласованный список работ.** Ни одной
|
||||
находки скилл не чинит сам, даже мелкой: правка по ходу разбора превращает
|
||||
разговор в работу и съедает то время, ради которого прогон и затевался.
|
||||
|
||||
Находки разбираются **по одной, сверху вниз**, и по каждой человек говорит одно
|
||||
из трёх:
|
||||
|
||||
- **берём** — находка становится задачей;
|
||||
- **не берём** — с причиной; причина уезжает в журнал дефектов `docs/review.md`,
|
||||
потому что отказ от находки это тоже решение о качестве;
|
||||
- **не находка** — проход ошибся; это тоже строка журнала, и по ней потом видно,
|
||||
какой проход даёт ложные срабатывания.
|
||||
|
||||
**Показывай находку целиком**, а не заголовком: оракул и последствие — это и есть
|
||||
то, по чему человек решает. Заголовок без оракула читается как мнение.
|
||||
|
||||
**Длинный список разбирается порциями.** Десяток пунктов за раз — потолок
|
||||
внимания, а не формальность; остальное ждёт следующей порции в том же прогоне.
|
||||
|
||||
## Задачи заводит `av-dev:task-track`
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси завести задачи по согласованному
|
||||
списку — у него на этот вход отдельный сценарий «задачи из ревью и аудита»: своя
|
||||
нарезка, свой формат, свои правила дублей. Формулировку, оракул и происхождение
|
||||
находки передавай **дословно**: пересказ теряет как раз оракул, а без него задача
|
||||
превращается в пожелание.
|
||||
|
||||
Заводить записи руками, править индексы или придумывать свой формат нельзя —
|
||||
мост между скиллами это вызов, а не путь к файлу.
|
||||
|
||||
## Запись в журнал ревью
|
||||
|
||||
**Прогон оставляет след в `docs/review.md`** — вызовом `av-dev:doc-sync`, который
|
||||
владеет этим документом. В следе: область, состав проходов, что взято задачами,
|
||||
что отвергнуто и почему, что проверить было невозможно.
|
||||
|
||||
**Второго вопроса здесь не задают, хотя `review.md` — документ рода «новое»**
|
||||
(`av-dev:doc-sync`, «Два рода правок»): слово по каждой находке человек уже сказал
|
||||
в разборе, и след цитирует ровно его решения. Правило то же, что у сужения
|
||||
проверок: спрашивается новое, которое заметил ты, а не то, что человек только что
|
||||
решил вслух.
|
||||
|
||||
Без этого следа второй прогон по той же области начнётся с нуля и предложит те же
|
||||
находки, от которых человек уже отказался, — а отказ, не оставивший записи,
|
||||
неотличим от непойманного.
|
||||
|
||||
## Доклад
|
||||
|
||||
- **область** — что смотрели, адресами;
|
||||
- **состав прогона** — какие проходы шли, какие темы закрыты, какие нет;
|
||||
- **находки** — сколько выжило после триажа, сколько взято задачами, сколько
|
||||
отвергнуто с причиной;
|
||||
- **заведённые задачи** — слагами, либо строка «каталога задач нет, список
|
||||
остаётся в докладе»;
|
||||
- **границы покрытия** — что проверить было невозможно: недоступный инструмент,
|
||||
неподнимаемая зависимость, область, до которой не дошли;
|
||||
- **отложенное, которое сняли** — какие строки «отложено» из отчётов ревью
|
||||
закрыты этим прогоном.
|
||||
|
||||
## Тонкости
|
||||
|
||||
- **Прогон не правит код** — ни строки. Единственный его артефакт, кроме
|
||||
разговора, это задачи и запись в журнале ревью.
|
||||
- **Область меньше — прогон лучше.** Модуль разбирается до конца, сервис целиком
|
||||
даёт список, который бросают на середине.
|
||||
- **Находка о процессе — тоже находка.** Пустой список отложенного, дефект,
|
||||
трижды проскочивший в одном узле, тема без дома — всё это идёт в доклад наравне
|
||||
с находками о коде.
|
||||
- **Задачи здесь нет, и границей служит только область.** Дифф, дельта-спеки,
|
||||
критерии приёмки — всё это про задачу; сюда они не приходят, и подставлять их
|
||||
«по аналогии» нельзя.
|
||||
@@ -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 и работает.
|
||||
|
||||
@@ -52,7 +52,7 @@ openspec init --tools claude
|
||||
Пересказ паспорта, инвариантов, конвенций и правил ревью сюда **не переносится**.
|
||||
Место для второго дома здесь самое частое: `context` читается при порождении
|
||||
каждого артефакта, туда удобно дописать «чтобы агент знал», и так заводятся копии
|
||||
инвариантов, состава гейта и правил выбора метки. Расходятся они молча, а
|
||||
инвариантов, состава гейта и правил ревью. Расходятся они молча, а
|
||||
замечают это в уже написанном предложении.
|
||||
|
||||
Разрез, по которому отличают одно от другого: **утверждение, которое можно
|
||||
|
||||
@@ -43,8 +43,8 @@ context: |
|
||||
Пересказа этих документов здесь нет намеренно: второй дом факта расходится с
|
||||
первым молча, и заметно это становится в предложении, которое уже написано.
|
||||
|
||||
Ревью: правило выбора метки и состав проходов здесь не пересказываем — их дом
|
||||
скилл av-dev:code-review, проектная настройка — docs/review.md.
|
||||
Ревью: состав проходов и глубину тем здесь не пересказываем — их дом скилл
|
||||
av-dev:code-review, проектная настройка — docs/review.md.
|
||||
|
||||
Конвенции кода: механизированное проверяет гейт, прозой остаётся
|
||||
docs/conventions/. Ни состав шагов гейта, ни перечень конвенций здесь не
|
||||
@@ -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 и отражение в документах молча → одна реплика о новом, где человек решает, что заводится: ADR, конвенция, задачи из урожая ревью → письмо одобренного → коммит → закрытие). Плановых стопов у сценария два, и оба про решения человека: чекпоинт до кода решает форму решения, реплика после кода — что из найденного переживёт задачу. Способ известен, а спека не меняется (тип 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 и 6 и проход `review-specs`
|
||||
(они завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
||||
подключай OpenSpec, а не вырождай цикл сценария; почему ветка деградации здесь
|
||||
@@ -239,8 +239,8 @@ description: "Взять одну задачу и довести её до за
|
||||
человек.
|
||||
|
||||
Обратной смены «решение → обслуживание» нет: задача, заведшая change, доводится
|
||||
циклом решения. Дельта-спеки, оказавшиеся пустыми, — находка ревью дизайна о
|
||||
самой постановке, а не повод свернуть на короткий путь из середины длинного.
|
||||
циклом решения. Дельта-спеки, оказавшиеся пустыми, — повод назвать это на
|
||||
чекпоинте, а не свернуть на короткий путь из середины длинного.
|
||||
|
||||
**Соблазн «разведаю по ходу» живёт именно здесь**, и он дорог тем, что выглядит
|
||||
экономией одного прогона. Разведка внутри решения не имеет своего чекпоинта:
|
||||
@@ -284,7 +284,7 @@ flowchart TD
|
||||
скилл написал бы сам, если бы писал.
|
||||
|
||||
Причина про контекст, и она одна. Оркестратор ведёт задачу целиком: выбрал
|
||||
сценарий, собирает чекпоинт, сверяет план прогона с исходом, пишет доклад, — а
|
||||
сценарий, собирает чекпоинт, сверяет перечень тем с исходом, пишет доклад, — а
|
||||
для всего этого надо помнить постановку, критерии приёмки и то, что человек
|
||||
одобрил. Письмо тянет в контекст ровно то, чего в докладе не будет ни строкой:
|
||||
содержимое тронутых файлов, вывод линтеров и гейта, перебранные варианты правки.
|
||||
@@ -293,19 +293,24 @@ 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), шаг 5; [maintain](references/maintain.md), шаг 4 |
|
||||
| правка оснастки в сценарии обслуживания | [maintain](references/maintain.md), шаг 2 |
|
||||
| архивация change и отражение в документах — `opsx:archive` и `av-dev:doc-sync` | [solve](references/solve.md), шаг 6, такт 1; [maintain](references/maintain.md), шаг 5 |
|
||||
| письмо одобренного нового в документы канона | [solve](references/solve.md), шаг 6, такт 3; [maintain](references/maintain.md), шаг 5 |
|
||||
|
||||
**Остальное остаётся оркестратору, и перечень закрыт:** выбор сценария и стопы,
|
||||
чекпоинт, вызовы `av-dev:code-review`, `av-dev:doc-sync`, `av-dev-git:commit` и
|
||||
`av-dev:task-track`, сверка плана с исходом, урожай и доклад. Ни одна из этих
|
||||
чекпоинт, вызовы `av-dev:code-review`, `av-dev-git:commit` и `av-dev:task-track`,
|
||||
сверка плана с исходом, урожай и доклад. **Коммит и закрытие задачи агенту не
|
||||
отдаются ни в одном сценарии** — они необратимы для учёта: закрытие удаляет запись
|
||||
и правит индексы, а коммит уезжает в историю. Оркестратор делает их сам, уже
|
||||
сверив перечень тем с исходом. Ни одна из этих
|
||||
работ не пишет файлов проекта — они и есть та работа, ради которой контекст
|
||||
берегут.
|
||||
|
||||
@@ -334,7 +339,7 @@ flowchart TD
|
||||
- **что делать**: файл задачи либо её текст дословно, критерии приёмки,
|
||||
идентификатор change;
|
||||
- **что читать**: `CLAUDE.md`, конвенции проекта, дельта-спеки change;
|
||||
- **находки — дословно**, как их вернул триаж или ревью дизайна, вместе с
|
||||
- **находки — дословно**, как их вернул триаж, вместе с
|
||||
оракулом;
|
||||
- **границы**: правится названное, соседнее не улучшается заодно; развилок агент
|
||||
не решает, задач не заводит, ничего не коммитит и наружу не ходит — правило
|
||||
@@ -348,11 +353,26 @@ flowchart TD
|
||||
|
||||
### Возврат — не длиннее экрана
|
||||
|
||||
Агент возвращает: что сделано, **адресами** тронутого; исход гейта и чем он
|
||||
прогнан; что не удалось и почему; вопросы, если по заданию их не разрешить.
|
||||
Агент возвращает: что сделано, **адресами** тронутого; исход гейта, чем он
|
||||
прогнан, где логи шагов и **отпечаток дерева сразу после прогона**; что не
|
||||
удалось и почему; вопросы, если по заданию их не разрешить. Отпечаток нужен
|
||||
ревью: по нему ступень автотестов засчитывает этот прогон вместо своего
|
||||
(`av-dev:code-review`, ступень 1) — без него гейт гоняется дважды на том же
|
||||
дереве.
|
||||
Диффа, пересказа кода и логов в возврате нет — иначе экономия, ради которой шаг
|
||||
и вынесен, отменяется в момент возврата.
|
||||
|
||||
**Чек-лист синка — единственное исключение из «не длиннее экрана».** Он приходит
|
||||
из хвостового агента целиком и целиком уезжает в доклад: тронутые документы
|
||||
поимённо, предложенное — строкой с основанием, нетронутые — одной строкой с общей
|
||||
причиной. Сжать его своими словами значит потерять принуждённое отрицание, ради
|
||||
которого шаг и существует.
|
||||
|
||||
**Предложения из этого чек-листа оркестратор не исполняет сам.** Они уезжают в
|
||||
реплику человеку вместе с урожаем ревью, и написанным становится только то, что
|
||||
он назвал (`solve.md`, шаг 6, такт второй). Агент, вернувший предложение, свою
|
||||
работу сделал — заведение нового не его решение и не твоё.
|
||||
|
||||
**Возврату на слово не верят, и перечитывать за агентом дифф для этого не надо.**
|
||||
Верят независимым артефактам: зелёному гейту, отчёту триажа, ревью следующего
|
||||
шага. Своей прозе здесь верить нельзя ровно по той причине, по которой ей не
|
||||
@@ -373,11 +393,21 @@ flowchart TD
|
||||
второй раз — делай сам и **скажи это строкой доклада**: прогон стоил дороже, чем
|
||||
должен, и это факт для человека, а не стоп.
|
||||
|
||||
## Автономность и плановый стоп
|
||||
## Автономность и плановые стопы
|
||||
|
||||
**У двух сценариев ровно один плановый стоп**, и стоят они в разных местах:
|
||||
у решения — объяснение после ревью дизайна, у разведки — варианты до первого
|
||||
написанного требования. Правило вокруг них общее.
|
||||
**Стопов у сценария не больше двух, и каждый — про решение человека, а не про
|
||||
ход работ.**
|
||||
|
||||
| Сценарий | Стоп до письма | Стоп после письма |
|
||||
| --- | --- | --- |
|
||||
| решение | чекпоинт: объяснение после предложения и до кода | реплика шага 6: что из найденного заводится |
|
||||
| разведка | чекпоинт вариантов до первого написанного требования | — исход и так уезжает в документы по выбранному варианту |
|
||||
| обслуживание | — планового нет | реплика шага 5, и только если появилось новое |
|
||||
|
||||
**Второй стоп короче первого и часто не случается вовсе.** Первый решает форму
|
||||
решения, и без ответа работа не идёт дальше; второй решает, что из найденного
|
||||
переживёт задачу, и при пустом списке нового его просто нет. Правило вокруг обоих
|
||||
общее.
|
||||
|
||||
**У обслуживания планового стопа нет вовсе, и это следствие, а не поблажка.**
|
||||
Один стоп с ожиданием ответа у него всё же есть — по найденной дельта-спеке, — но
|
||||
@@ -509,12 +539,14 @@ change, у второго — сверенный состав гейта и си
|
||||
текущем worktree и на текущей ветке: не делай `git checkout`/`switch`, не
|
||||
создавай веток, не пушь.
|
||||
- Прогон проходит **не больше одного** чекпоинта, и это норма, а не упрощение.
|
||||
Два стопа за одну задачу — цена незнания способа, и платится она двумя
|
||||
Два чекпоинта за одну задачу — цена незнания способа, и платится она двумя
|
||||
прогонами, а не одним длинным. У обслуживания чекпоинта нет ни одного, и это
|
||||
тоже норма: там нечего решать.
|
||||
тоже норма: там нечего решать. Реплика о новом чекпоинтом не является и этого
|
||||
счёта не касается — она решает не форму решения, а судьбу находок.
|
||||
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
|
||||
подтверждать механику: чекпоинт — единственное место, где ждут ответа, а в
|
||||
обслуживании такого места нет вовсе.
|
||||
подтверждать механику. Мест, где **ждут ответа**, ровно два, и оба названы в
|
||||
«Автономности»: чекпоинт до кода и реплика о новом после него. Третьего нет ни
|
||||
в одном сценарии, и заводить его нельзя.
|
||||
- **Сценарий назван вслух — значит, его можно оспорить.** Человек, увидевший в
|
||||
первой реплике «иду разведкой, потому что способа не видно», поправит выбор
|
||||
одной фразой; молча выбранный сценарий он поправит через полчаса работы.
|
||||
|
||||
@@ -19,10 +19,9 @@
|
||||
|
||||
**У обслуживания нет дельта-спек по построению.** Тип `chore` определён через
|
||||
«наблюдаемое поведение не меняется», а на дельтах стоит весь цикл: `propose`
|
||||
их порождает, разметка выведена **из них**, `review-specs` сверяет **с ними**,
|
||||
объяснение чекпоинта собирается из `proposal.md` и `design.md`, `archive` вливает
|
||||
их в актуальные спеки. Change без дельт — пустой артефакт, который потом надо
|
||||
архивировать, и разметчик по нему назовёт не те темы.
|
||||
их порождает, `review-specs` сверяет **с ними**, объяснение чекпоинта собирается
|
||||
из `proposal.md` и `design.md`, `archive` вливает их в актуальные спеки. Change
|
||||
без дельт — пустой артефакт, который потом надо архивировать.
|
||||
|
||||
Шаги цикла здесь не пропущены — **им нечего обрабатывать**. Отсюда и состав
|
||||
сценария: выпали ровно те шаги, у которых нет предмета, и не выпал ни один из
|
||||
@@ -69,7 +68,7 @@
|
||||
|
||||
## Дельта нашлась по ходу — стоп, и у него свой порядок
|
||||
|
||||
Признак тот же, что на шаге 7 сценария решения: **меняется ли то, что записано в
|
||||
Признак тот же, что у отработки ревью в решении (шаг 5): **меняется ли то, что записано в
|
||||
`openspec/specs/`**. Обнаружилось, что меняется, — работа перестала быть
|
||||
обслуживанием в ту же секунду, и продолжать её нельзя: коммит обслуживания
|
||||
заявляет «поведение не менялось», а оно меняется.
|
||||
@@ -125,8 +124,8 @@
|
||||
|
||||
**Третьего решения — «доделать как обслуживание» — нет.** Оно и есть то самое
|
||||
молчаливое изменение поведения, против которого стоит весь разрез: под коммитом,
|
||||
заявляющим «поменяли оснастку», уехала бы правка, не прошедшая ни ревью дизайна,
|
||||
ни чекпоинта, и не оставившая следа в спеках.
|
||||
заявляющим «поменяли оснастку», уехала бы правка, не прошедшая ни чекпоинта, ни
|
||||
ревью цикла задачи, и не оставившая следа в спеках.
|
||||
|
||||
**Сделанное не выбрасывается ни при каком из двух решений.** Оно остаётся в
|
||||
рабочем дереве незакоммиченным: при переформулировке уезжает в change следующим
|
||||
@@ -154,9 +153,12 @@
|
||||
решать, вырождается в обряд одобрения и обесценивает те стопы, где решать есть
|
||||
что.
|
||||
|
||||
**Место, где ответа всё же ждут, одно, и плановым оно не является** — стоп по
|
||||
найденной дельте (раздел «Дельта нашлась по ходу»). Через него проходят не все
|
||||
прогоны, а только те, где задача оказалась не тем, чем объявлена.
|
||||
**Мест, где ответа всё же ждут, два, и через оба проходят не все прогоны.**
|
||||
Первое — стоп по найденной дельте (раздел «Дельта нашлась по ходу»), и плановым
|
||||
он не является: через него идут те прогоны, где задача оказалась не тем, чем
|
||||
объявлена. Второе — **реплика о новом на шаге 5**, и она случается, только если
|
||||
обслуживание завело в документах что-то, чего не было: запрет или инвариант.
|
||||
Обычный прогон обслуживания не проходит ни через одно из двух.
|
||||
|
||||
**Правило необратимого при этом действует полностью** (SKILL.md, «Когда
|
||||
спрашивать вне чекпоинта»), и здесь оно опаснее, чем кажется. Единственный
|
||||
@@ -295,6 +297,10 @@ ADR: список источников канон закрыл двумя — а
|
||||
Прогони гейт и добейся зелёного — он же условие следующего шага: пока гейт
|
||||
красный, проходы с мнением не запускаются.
|
||||
|
||||
**Сразу после зелёного сними отпечаток дерева** (`av-dev:code-review`, ступень 1)
|
||||
и сохрани его вместе со сводкой и путём к логам шагов. Шаг 4 передаёт их ревью, и
|
||||
тогда ступень автотестов не гоняет тот же гейт второй раз.
|
||||
|
||||
**Поведенческая верификация здесь другая, чем в решении.** Проверяется не новое
|
||||
поведение, а то, что прежнее не поехало: команда из `CLAUDE.md` поднимается, шаг
|
||||
сборки отрабатывает, хук ставится на чистом клоне. **У оснастки, заводимой
|
||||
@@ -304,41 +310,39 @@ ADR: список источников канон закрыл двумя — а
|
||||
|
||||
### 4. Ревью — план фиксирован сценарием
|
||||
|
||||
Вызови Skill **`av-dev:code-review`**, дав базу диффа, режим и **план сценария**.
|
||||
Change ты не передаёшь — его нет.
|
||||
Вызови Skill **`av-dev:code-review`**, дав базу диффа, режим, **план сценария** и
|
||||
**исход гейта с шага 3** — сводку, путь к логам шагов и отпечаток дерева. Change
|
||||
ты не передаёшь — его нет.
|
||||
|
||||
**Разметчик здесь не зовётся, и это правило, а не пропуск.** Обе оси, по которым
|
||||
он судит, у обслуживания не определены: размер он меряет по `proposal.md`,
|
||||
`design.md`, `tasks.md` и дельта-спекам, а незнакомость — по форме решения,
|
||||
которой здесь нет (незнакомое ушло в разведку шагом 1). Разметчик без своего
|
||||
корпуса вернул бы метку, выведенную из ничего.
|
||||
**План у сценария свой, и он не совпадает с перечнем тем цикла задачи.** Тема
|
||||
`requirements` там есть, а здесь её предмета нет вовсе; `operations` в цикле
|
||||
закрыта сверкой с инвариантами внутри `review-code`, а здесь её берёт `basics` —
|
||||
правка оснастки задевает выкладку, откат и соседей чаще, чем что-либо ещё, и
|
||||
инвариантов на этот счёт у проекта обычно нет.
|
||||
|
||||
Поэтому план у сценария **свой и постоянный**, и глубину он называет сам —
|
||||
проходы берут её из метки, а метки здесь нет:
|
||||
|
||||
<!-- дом: план-без-метки -->
|
||||
<!-- дом: план-обслуживания -->
|
||||
|
||||
| Тема | Дом | Кто закрывает | Глубина и вход | Когда |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `autotests` | `CLAUDE.md`, семантика гейта | `review-autotests` | как обычно: гейт запускается целиком | всегда |
|
||||
| `operations` | `architecture.*`, раздел эксплуатации | `review-basics` | **сверка**: дом темы против диффа, потолок 2 | всегда |
|
||||
| `conventions` + технический разбор | `conventions.*` | `review-code` | вход `small`: только индекс конвенций; потолки 3 технических и 2 конвенционных; **третья половина включена** — сверка с инвариантами `CLAUDE.md`, потолок 1 | дифф трогает код, а не только оснастку |
|
||||
| `conventions` + технический разбор | `conventions.*` | `review-code` | как в цикле: дом конвенций целиком, потолок 4 конвенционных, у техники потолка нет; сверка с инвариантами `CLAUDE.md` по темам `security`, `operations`, `architecture`, потолок 1 | дифф трогает код, а не только оснастку |
|
||||
|
||||
<!-- /дом: план-без-метки -->
|
||||
<!-- /дом: план-обслуживания -->
|
||||
|
||||
**Глубина названа в плане потому, что иначе её неоткуда взять.** Вход и потолки
|
||||
`review-code` заданы меткой, у `review-basics` меткой задана и сама возможность
|
||||
запуска; на прогоне без метки оба взяли бы их наугад — то есть по-разному от
|
||||
прогона к прогону, и молча.
|
||||
**Глубина названа в плане потому, что иначе её неоткуда взять.** У `review-basics`
|
||||
и тема, и глубина приходят заданием — в цикле он держит только свои темы проекта,
|
||||
а здесь ему дают чужую; без строки плана он взял бы её наугад, то есть по-разному
|
||||
от прогона к прогону и молча.
|
||||
|
||||
**Третья половина `review-code` включена намеренно.** В конвейере она живёт при
|
||||
метке `small`, где приёмник тем не запускается, и сверяет дифф с записанными
|
||||
инвариантами `CLAUDE.md` по темам `security`, `operations` и `architecture`.
|
||||
Здесь у неё та же работа: без неё `security` не смотрит вообще никто.
|
||||
**`review-code` идёт тем же составом, что в цикле, и это не совпадение.** Обе его
|
||||
половины и сверка с инвариантами постоянны — от прогона они не зависят, потому и
|
||||
переносятся сюда без оговорок. Единственное, что план решает за него, — идти ли
|
||||
вообще: правка, тронувшая только оснастку, кода не меняла.
|
||||
|
||||
Триаж обязателен, как и на всяком прогоне: он единственный сток и единственный,
|
||||
кто сверяет план с исходом. На его вход подаётся этот план — вместо плана
|
||||
разметки, которого нет.
|
||||
кто сверяет план с исходом. На его вход подаётся этот план — вместо перечня тем
|
||||
цикла задачи.
|
||||
|
||||
**Условие третьей строки проверяемое, и смотрится оно по диффу**, а не по
|
||||
намерению: обновление зависимости или правка файла CI кода не трогают, чистка и
|
||||
@@ -346,9 +350,10 @@ Change ты не передаёшь — его нет.
|
||||
«здесь ошибка в логике», и чистка, прошедшая без него, проверена только на то,
|
||||
что она собирается.
|
||||
|
||||
**Сигнал о заниженной метке на этом прогоне не работает** — метки нет, и
|
||||
поднимать нечего. Его место занимает признак сценария: показалось, что глубины
|
||||
мало, потому что задача крупнее заявленного, — ищи дельту, а не метку.
|
||||
**Сигнал «просит глубокого ревью» работает и здесь**, но читается иначе: у
|
||||
обслуживания поднимать нечего — состав фиксирован сценарием. Показалось, что
|
||||
глубины мало, потому что задача крупнее заявленного, — ищи дельту, а не глубину;
|
||||
всё прочее уходит строкой «отложено в `av-dev:code-deep-review`».
|
||||
|
||||
**Границы покрытия называются полностью:**
|
||||
|
||||
@@ -363,14 +368,50 @@ Change ты не передаёшь — его нет.
|
||||
|
||||
Отработка — как в решении: помеченное `инлайн` чинит **агент** (SKILL.md, «Кто
|
||||
пишет»), находки уходят ему дословно с оракулом, гейт после правок гоняет он же,
|
||||
логировать их не надо; `развилка` — вопросом в запись, и агенту она не отдаётся. Отложенные находки собери в секцию
|
||||
доклада `Урожай`; задачи из него заводит `av-dev:task-track`, не ты.
|
||||
логировать их не надо; `развилка` — вопросом в запись, и агенту она не отдаётся.
|
||||
Отложенные находки собери в секцию доклада `Урожай`.
|
||||
|
||||
### 5. Синк документации — главный шаг этого сценария
|
||||
**Задачи из урожая — по слову человека, и спрашивается это репликой шага 5**,
|
||||
вместе с новым в документах: правило общее для всех прогонов конвейера
|
||||
(`av-dev:code-review`, «Что происходит с находками дальше»), и обслуживание не
|
||||
исключение. Сказал «заводим» — зовёшь `av-dev:task-track` сам, сценарий «задачи
|
||||
из ревью и аудита»; не сказал — урожай остаётся строками доклада.
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`.** Правило то же и такое же жёсткое:
|
||||
**принуждённое отрицание** — каждый документ канона либо назван обновлённым, либо
|
||||
получает «не требуется, потому что…». Нетронутые группируются одной строкой.
|
||||
### 5. Синк документации — главный шаг этого сценария, и делает его агент
|
||||
|
||||
**Синк уходит агенту** (SKILL.md, «Кто пишет»): работа письменная и нормирована
|
||||
чек-листом скилла `av-dev:doc-sync`, а не суждением оркестратора. В задании —
|
||||
корень проекта, база диффа, что было тронуто правкой, требование принуждённого
|
||||
отрицания и требование довести гейт до зелёного после правок. Вычитку языка
|
||||
`av-dev:doc-sync` зовёт сам.
|
||||
|
||||
**Правило то же и такое же жёсткое: принуждённое отрицание** — каждый документ
|
||||
канона либо назван обновлённым, либо получает «не требуется, потому что…».
|
||||
Нетронутые группируются одной строкой. Возврат приходит в этой же форме и уезжает
|
||||
в доклад целиком: тронутое без нетронутого не отличается от невыполненного шага.
|
||||
|
||||
**Второе правило синка тоже действует: отражение пишется молча, новое
|
||||
предлагается** (дом — раздел «Два рода правок» скилла `av-dev:doc-sync`). Здесь
|
||||
оно почти ничего не стоит: обслуживание двигает **факты** — команды, шаги гейта,
|
||||
зависимости поимённо, пути, имя ветки, числа настроек, — а факт в документе,
|
||||
разошедшийся с кодом, это отражение по определению.
|
||||
|
||||
**Повод для реплики у этого сценария один — новый запрет или инвариант в
|
||||
`CLAUDE.md`**: он свяжет все будущие задачи, и заводить его молча нельзя.
|
||||
Сужение проверок в `review.*` поводом не является, хотя тоже новое: проверки
|
||||
сузил человек, и слово по ним уже сказано (`av-dev:doc-sync`, «Два рода правок»).
|
||||
К этому же поводу примыкает урожай ревью с шага 4 — спрашиваются они одной
|
||||
репликой, а не двумя.
|
||||
|
||||
**Нового нет — реплики нет**, и шаг кончается возвратом агента; так идёт
|
||||
большинство прогонов обслуживания.
|
||||
|
||||
**Реплика была — идёт второй заход тем же агентом**, и на нём висит то же, что в
|
||||
решении: письмо одобренного, вычитка `doc-wording` по всей пачке и гейт до
|
||||
зелёного. Первый заход снимает их с себя ровно тогда, когда вернул непустой
|
||||
список предложений, — порядок и его довод описаны в [solve.md](solve.md), шаг 6.
|
||||
Задачи из урожая при этом заводишь **ты сам** вызовом `av-dev:task-track`, а не
|
||||
агент: индексы учёта правит тот, кто коммитит.
|
||||
|
||||
**Здесь этот шаг весит больше, чем в решении, и вот почему.** Обслуживание не
|
||||
меняет поведения — значит, почти всё, что оно меняет, это документация: команды,
|
||||
@@ -452,10 +493,14 @@ Change ты не передаёшь — его нет.
|
||||
выдуманному пользователю;
|
||||
- **состав гейта до и после**, если правка его трогала; не сверялся — почему;
|
||||
- по каждому критерию приёмки: **оракул и наблюдаемый исход**;
|
||||
- **`Урожай`** — отложенные находки списком;
|
||||
- **строка границ покрытия**: план сценария фиксирован, разметчик не запускался,
|
||||
`requirements` не смотрел никто, а `security` и `architecture` — только против
|
||||
записанных инвариантов, и то если шёл проход `code`.
|
||||
- **`Урожай`** — отложенные находки списком и **что человек по нему решил**;
|
||||
- **что заведено нового в документах** и что предложено и отвергнуто — по именам
|
||||
записей; отказ виден только здесь;
|
||||
- **сигнал сверки** — строка синка о том, сколько задач сделано с прошлого
|
||||
прогона `av-dev:doc-healthcheck`, либо что сверки не было ни разу;
|
||||
- **строка границ покрытия**: план сценария фиксирован; темы `requirements` в нём
|
||||
нет — её не смотрел никто, а `security` и `architecture` смотрелись только
|
||||
против записанных инвариантов, и то если шёл проход `code`.
|
||||
|
||||
## Тонкости сценария
|
||||
|
||||
|
||||
@@ -281,6 +281,13 @@ git и читается диффом, а второй стоп на каждой
|
||||
незачем. Но **названо должно быть каждое место, куда ты писал**, — доклад без
|
||||
перечня адресов неотличим от доклада о ненаписанном.
|
||||
|
||||
**Правило «новое по слову» здесь тоже не задаёт второго вопроса**, хотя ответ
|
||||
разведки — новое от первой до последней строки. Слово уже сказано **чекпоинтом
|
||||
вариантов**: человек выбрал вариант и тем самым заказал запись. Спросить ещё раз
|
||||
значило бы переспросить только что одобренное — и заодно предложить выбросить
|
||||
работу, ради которой прогон и шёл. Что записать нового сверх выбранного —
|
||||
например ADR по решению с ценой, — предлагается, как везде.
|
||||
|
||||
**Документов канона в проекте нет** — писать ответ некуда: назови это исходом,
|
||||
предложи завести канон скиллом `av-dev:canon` и оставь ответ в докладе
|
||||
целиком, чтобы работа не пропала. Заводить `docs/` мимо канона нельзя.
|
||||
@@ -391,8 +398,8 @@ git и читается диффом, а второй стоп на каждой
|
||||
## Доклад разведки
|
||||
|
||||
Общая форма доклада — в SKILL.md; у разведки он свой, потому что докладывать
|
||||
нечего из того, о чём спрашивают решение (ни метки ревью, ни критериев приёмки,
|
||||
ни архивного change). Коротко, и в нём обязательно:
|
||||
нечего из того, о чём спрашивают решение: ни критериев приёмки, ни архивного
|
||||
change, ни исхода ревью — кода она не писала. Коротко, и в нём обязательно:
|
||||
|
||||
- **исход** одним из четырёх слов;
|
||||
- **вопрос и ответ** — по фразе на каждое. Ответ, который не сворачивается во
|
||||
@@ -401,6 +408,8 @@ git и читается диффом, а второй стоп на каждой
|
||||
- **какие задачи заведены и уточнены** — слагами;
|
||||
- **что вычитано и чем** — пачка документов и пачка записей, каждая со своими
|
||||
проходами; не вычитанное называется прямо, вместе с причиной;
|
||||
- **сигнал сверки** — строка синка о том, сколько задач сделано с прошлого
|
||||
прогона `av-dev:doc-healthcheck`, либо что сверки не было ни разу;
|
||||
- **что осталось неизвестным** и чего это стоит: разведка без этой строки
|
||||
сообщает «выяснено», не сообщая, что именно осталось не выяснено;
|
||||
- **рамки**, если они ограничили работу: докуда копали и почему остановились.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Сценарий «решение»
|
||||
|
||||
Способ решения известен, спорно только как. Проводит задачу от постановки до
|
||||
закрытия и **пишет код**: цикл Spec Driven Development с одним плановым стопом —
|
||||
объяснением после ревью дизайна.
|
||||
закрытия и **пишет код**: цикл Spec Driven Development с двумя плановыми стопами —
|
||||
объяснением сразу после предложения и репликой о новом после ревью.
|
||||
|
||||
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
|
||||
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
|
||||
@@ -11,14 +11,12 @@
|
||||
пересказывается.
|
||||
|
||||
**OpenSpec — жёсткая предпосылка именно этого сценария** (SKILL.md,
|
||||
«Предпосылки»): на нём стоят шаги 2, 6 и 8, проход `review-specs` и ревью
|
||||
дизайна.
|
||||
«Предпосылки»): на нём стоят шаги 2, 4 и 6 и проход `review-specs`.
|
||||
|
||||
Тонкая обёртка над каноническими скиллами `opsx:propose` / `opsx:apply` /
|
||||
`opsx:archive` — их шаги не переизобретаются, а **зовёт их агент**, не ты
|
||||
(SKILL.md, «Кто пишет: письмо уходит агентам»). Ревью — скилл
|
||||
`av-dev:code-review`; он же держит правило выбора метки, а называет её агент
|
||||
`review-scope` — один раз на задачу, для обеих стадий ревью.
|
||||
`av-dev:code-review`; состав его прогона постоянный, выбирать и размечать нечего.
|
||||
|
||||
## Ход работы
|
||||
|
||||
@@ -27,21 +25,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. ревью кода — постоянный состав<br/>+ отработка замечаний агентом"]
|
||||
s6["6. opsx:archive + отражение в документах —<br/>одним агентом"]
|
||||
s6q(["РЕПЛИКА: что заводим из нового —<br/>ADR, конвенция, задачи из урожая"])
|
||||
s6b["такт 3: задачи — оркестратором,<br/>документы, вычитка и гейт — агентом"]
|
||||
s7["7. коммит работы — av-dev-git:commit"]
|
||||
s8["8. закрыть задачу — 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 --> s6q --> s6b --> s7 --> s8
|
||||
s3 -.->|"скорректировать:<br/>правка спек и дизайна"| s3
|
||||
s5 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
s6 -.->|"нового нет:<br/>реплики нет"| s7
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||||
@@ -66,11 +63,12 @@ flowchart TD
|
||||
Задача сделана, когда верно всё:
|
||||
|
||||
1. гейт проекта зелёный;
|
||||
2. ревью проведено, **план прогона сверен с исходом по каждой теме**, темы без
|
||||
отчёта и без дома названы в границах покрытия;
|
||||
2. ревью проведено, **перечень тем сверен с исходом по каждой**, темы без отчёта
|
||||
и без дома названы в границах покрытия;
|
||||
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
|
||||
чекпоинт был пройден заново;
|
||||
4. change заархивирован, дельты влиты в актуальные спеки;
|
||||
4. change заархивирован, дельты влиты в актуальные спеки, и по **каждому**
|
||||
документу канона назван исход — правка, предложение или отрицание с причиной;
|
||||
5. коммит сделан в текущую ветку;
|
||||
6. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
|
||||
оракул и наблюдаемый исход** — «прогнал вот это, увидел вот то». Это **доклад,
|
||||
@@ -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,29 @@ flowchart TD
|
||||
`design.md`, с причиной отказа по каждому отвергнутому.
|
||||
|
||||
**`proposal.md` пишется так, чтобы его понял человек, не читавший спек.** Это не
|
||||
стилистическое пожелание: из него собирается чекпоинт шага 5, и переписывать его
|
||||
стилистическое пожелание: из него собирается чекпоинт шага 3, и переписывать его
|
||||
там заново значит завести второй дом для одного объяснения. Требование стоит в
|
||||
`openspec/config.yaml`, `rules.proposal` — то есть применяется в момент
|
||||
порождения артефакта, а не вспоминается после.
|
||||
|
||||
### 3. Разметка задачи — агент `review-scope`
|
||||
### 3. Чекпоинт: объяснение
|
||||
|
||||
**Один запуск на всю задачу, и он обслуживает обе стадии ревью.** Запусти
|
||||
агента `review-scope`, дав ему корень проекта, идентификатор change, базу диффа и
|
||||
запись задачи. Кода на этот момент нет, и это условие его работы, а не помеха.
|
||||
**Остановись и объясни человеку, что происходит.** Первый из двух плановых стопов
|
||||
сценария, и в отличие от второго он обязателен для всякой задачи: реплика шага 6
|
||||
случается только тогда, когда есть что заводить, а чекпоинт — всегда.
|
||||
|
||||
Он возвращает **план задачи**:
|
||||
Он стоит **сразу после предложения и до кода** — намеренно. Раньше между
|
||||
`propose` и чекпоинтом стояла стадия ревью дизайна, и человек читал объяснение,
|
||||
уже просеянное машиной. Стадию сняли ради времени прогона, и просеивать теперь
|
||||
нечем: человек читает предложение как оно есть. Взамен стоп пришёл **раньше** —
|
||||
коррекция здесь стоит правки спеки, а не переписывания готового кода.
|
||||
|
||||
- **размер** (малое / среднее / крупное) и **сложность** (знакомое /
|
||||
незнакомое), каждое с обоснованием по факту;
|
||||
- **метку** как максимум по двум осям: `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. Чекпоинт: объяснение
|
||||
|
||||
**Остановись и объясни человеку, что происходит.** Единственный плановый стоп
|
||||
этого сценария, и он обязателен для всякой задачи.
|
||||
|
||||
Он стоит **после** ревью дизайна намеренно. Человек читает объяснение, уже
|
||||
просеянное машиной: то, что поймал бы `review-specs`, до него не доходит, а
|
||||
внимание — самый дорогой ресурс процесса, и тратить его на выловимое машиной
|
||||
нельзя.
|
||||
**Это единственное место процесса, где решается форма решения, и решает её
|
||||
человек.** Ревью после кода судит корректность и механику против записанного
|
||||
критерия; «то ли это решение» там не спрашивает ни один проход, а глубокое ревью
|
||||
области придёт позже и не всегда. Значит, чекпоинт — не формальность и не
|
||||
доклад о ходе работ: одобренное здесь уезжает в код без второго суждения о
|
||||
замысле.
|
||||
|
||||
**Объяснение не сочиняется заново — оно собирается из артефактов**, `proposal.md`
|
||||
и `design.md`. Третий пересказ был бы третьим домом одного и того же и разошёлся
|
||||
@@ -217,7 +160,7 @@ flowchart TD
|
||||
- **что человек увидит иначе**, когда это будет сделано;
|
||||
- **чего мы намеренно не делаем** и почему — граница scope ловится хуже всего;
|
||||
- **чем рискуем и что осталось нерешённым** — сюда съезжаются развилки,
|
||||
накопленные до этого места, и находки ревью с пометкой `развилка`;
|
||||
накопленные до этого места;
|
||||
- **что дальше**, если возражений нет;
|
||||
- **критерии приёмки, если постановка пришла текстом и не назвала их** —
|
||||
предложенными, а не принятыми: человек их подтверждает или правит здесь же.
|
||||
@@ -241,20 +184,23 @@ 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, «Возврат — не длиннее экрана»): его
|
||||
передача на шаг 5 избавляет ревью от второго прогона того же гейта.
|
||||
|
||||
Код — по конвенциям проекта
|
||||
(каталог `docs/conventions/`). Меняешь схему — обнови её описание в документации
|
||||
@@ -270,66 +216,56 @@ flowchart TD
|
||||
**Сервис не оставляем лежать.** Если запуск упал — агент чинит или откатывает до
|
||||
конца шага; возврат с лежащим сервисом — незакрытый шаг, а не исход.
|
||||
|
||||
### 7. Ревью кода — та же метка
|
||||
### 5. Ревью кода — состав постоянный
|
||||
|
||||
Вызови Skill **`av-dev:code-review`**, дав ссылку на change `<id>`,
|
||||
базу диффа, **план разметки с шага 3** и режим запуска.
|
||||
Вызови Skill **`av-dev:code-review`**, дав ссылку на change `<id>`, базу диффа,
|
||||
режим запуска и **исход гейта с шага 4** — сводку, путь к логам шагов и отпечаток
|
||||
дерева.
|
||||
|
||||
**Метку ты не выбираешь, и это правило, а не упрощение.** Её назвал
|
||||
`review-scope` ещё на шаге 3 — по размеру и сложности, с обоснованием по каждой
|
||||
оси. Причина в разведённости: ты только что написал этот код, и решать, насколько
|
||||
глубоко его проверять, тебе нельзя — под давлением «я почти закончил» решение
|
||||
известно заранее. Правило выбора живёт в скилле конвейера —
|
||||
`av-dev:code-review`, `references/review-levels.md`; проектные
|
||||
триггеры — в `docs/review.*`, подраздел «Триггеры метки».
|
||||
|
||||
**Метка не пересматривается по факту диффа.** Дифф может выйти крупнее, чем
|
||||
ожидалось при разметке, — это не повод её поднимать: пересмотр означал бы второй
|
||||
запуск разметчика, ровно то, ради устранения чего он и переехал на шаг 3.
|
||||
|
||||
**Считаешь метку заниженной — скажи это в докладе строкой, а не переспорь.**
|
||||
Разметчик вправе и поднять, и понизить; твоё несогласие это факт для человека, а
|
||||
не команда конвейеру. Место, где такое несогласие превращается в изменение
|
||||
правил, — журнал дефектов `docs/review.md`, и только постфактум.
|
||||
|
||||
**Плана нет — ревью кода не запускается.** Триаж требует план обязательным
|
||||
входом: без него он не может сверить, все ли размеченные темы вернули отчёт, а
|
||||
эта сверка — единственная защита от молчащего пропуска. Потерял план (прервалась
|
||||
сессия, ушёл контекст) — повтори шаг 3, а не гони прогон без него.
|
||||
**Выбирать и размечать нечего.** Состав прогона один и тот же на всякой задаче:
|
||||
гейт, сверка со спекой, разбор кода, триаж; приёмник тем идёт, когда у проекта
|
||||
есть свои темы. Прежде между кодом и ревью стоял отдельный проход разметки — он
|
||||
считал размер по диффу, сложность по постановке и выдавал метку, из которой
|
||||
выводился состав. Метка снята вместе с ним: цикл задачи проверяет корректность и
|
||||
механику, а этой работе нечего добавить и нечего убавить от размера изменения.
|
||||
|
||||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||||
знает свои рёбра: гейт открывает проходы с мнением, проходы с пометкой «держит
|
||||
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
||||
доказанной), триаж — сток. Просить **`линейно`** нужно только по причине, и она
|
||||
называется строкой: так сказал оператор; машина занята чем-то ещё; идёт разбор
|
||||
самого конвейера.
|
||||
знает свои рёбра: гейт открывает проходы с мнением, триаж — сток. Просить
|
||||
**`линейно`** нужно только по причине, и она называется строкой: так сказал
|
||||
оператор; машина занята чем-то ещё; идёт разбор самого конвейера.
|
||||
|
||||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||||
покрытия.
|
||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка`, секцией `Урожай`,
|
||||
секцией отложенного в глубокое ревью и границами покрытия.
|
||||
|
||||
**Сверь план прогона с исходом, прежде чем коммитить.** Отчёт начинается планом
|
||||
разметчика — таблицей «тема → дом → глубина → кто закрывает», — и против каждой
|
||||
темы обязан стоять исход. Тема без отчёта и тема без дома — разные вещи, и обе
|
||||
должны быть названы. Реестр короткий — темы ядра плюс свои проекта, — и сверка стоит
|
||||
одного взгляда.
|
||||
**Сверь перечень тем с исходом, прежде чем коммитить.** Отчёт начинается таблицей
|
||||
«тема → кто закрывает → против чего», и против каждой темы обязан стоять исход.
|
||||
Тема без отчёта и тема без дома — разные вещи, и обе должны быть названы.
|
||||
Реестр постоянный и короткий, сверка стоит одного взгляда.
|
||||
|
||||
#### Отработка, и здесь появляется одно новое правило
|
||||
#### Отработка — чинится молча, спрашивается редко
|
||||
|
||||
Помеченное `инлайн` чинит **агент** (SKILL.md, «Кто пишет»): находки уходят ему
|
||||
**дословно, вместе с оракулом**, одним заданием на весь урожай инлайна, и гейт
|
||||
после правок гоняет он же. Логировать их по-прежнему не надо. `развилка` —
|
||||
вопросом в запись (он уже сформулирован триажем, его остаётся перенести), и
|
||||
агенту она не отдаётся.
|
||||
после правок гоняет он же. Логировать их не надо. **Это умолчание, и оно
|
||||
широкое** — прогон, вернувший человеку список замечаний вместо готового
|
||||
результата, свою работу не сделал.
|
||||
|
||||
`развилка` — вопросом в запись (он уже сформулирован триажем, его остаётся
|
||||
перенести), и агенту она не отдаётся. Оснований у неё три, и все узкие: правка
|
||||
меняет **дельта-спеки**, находка сидит в **необратимом** месте (миграция, формат
|
||||
на диске, публичный контракт), находка трогает **инвариант** `CLAUDE.md`.
|
||||
Развилок больше двух на задачу — это факт для доклада: либо задача не та, либо
|
||||
разметка действий съехала.
|
||||
|
||||
**Находка, отменяющая одобренный дизайн, отменяет и одобрение.** Признак
|
||||
проверяемый: **меняются ли дельта-спеки**.
|
||||
|
||||
- не меняются — находка внутри дизайна, дожимай сам, это обычная отработка;
|
||||
- меняются — решение стало другим, а одобрено было прежнее. Повтори шаг 3
|
||||
(разметка выведена из дельта-спек) и **вернись на чекпоинт шага 5** с тем, что
|
||||
изменилось и почему. Такая находка агенту не отдаётся ни при каких условиях:
|
||||
она отменяет одобрение, а это разговор с человеком.
|
||||
- меняются — решение стало другим, а одобрено было прежнее. **Вернись на чекпоинт
|
||||
шага 3** с тем, что изменилось и почему; дальше задача идёт своим ходом заново —
|
||||
код, ревью. Такая находка агенту не отдаётся ни при каких условиях: она отменяет
|
||||
одобрение, а это разговор с человеком.
|
||||
|
||||
**Это правило старше правила о развилке.** Находка класса `развилка`, чьё
|
||||
основание — «надо менять спеку», подпадает под оба; побеждает возврат на
|
||||
@@ -340,38 +276,109 @@ flowchart TD
|
||||
ревью, не значит ничего, а человек при этом уверен, что одобрил именно то, что
|
||||
уехало в коммит.
|
||||
|
||||
**Урожай — списком, не задачами.** Отложенные находки (реальный `major` не для
|
||||
этого мерджа, развилка, решённая «потом», пачка `nit`) собери в секцию доклада
|
||||
`Урожай`: формулировка, оракул, откуда взялась. Задачи из него **заводит не этот
|
||||
скилл** — их заводит `av-dev:task-track` своим сценарием «задачи из ревью и
|
||||
аудита»: своя нарезка, свой формат, свои правила дублей. Твоя обязанность — не
|
||||
потерять и передать.
|
||||
#### Урожай — список в докладе, задачи только по слову человека
|
||||
|
||||
Отложенные находки (реальный `major` не для этого мерджа, развилка, решённая
|
||||
«потом», пачка `nit`) собери в секцию доклада `Урожай`: формулировка, оракул,
|
||||
откуда взялась.
|
||||
|
||||
**Задачи из урожая заводятся только тогда, когда человек сказал «заводим».**
|
||||
Спрашивается это **не здесь, а на шаге 6** — там же, где спрашивается новое в
|
||||
документах, и той же одной репликой: два вопроса подряд про одно и то же («что из
|
||||
найденного заводим») стоили бы человеку двух переключений вместо одного. Сюда
|
||||
урожай складывается, а не выносится.
|
||||
|
||||
Сказал «заводим» — зовёшь `av-dev:task-track` **ты сам**, тактом третьим шага 6:
|
||||
у него на этот вход отдельный сценарий «задачи из ревью и аудита» — своя нарезка,
|
||||
свой формат, свои правила дублей, и находка передаётся дословно. Не сказал —
|
||||
урожай остаётся строками доклада, и это исход, а не потеря.
|
||||
|
||||
**Молча беклог не наполняется.** Очередь работ ведёт человек, и задача, заведённая
|
||||
за него по ходу чужого прогона, отнимает у него ровно то решение, ради которого
|
||||
очередь и существует. Прежде вызов `av-dev:task-track` был обязательным шагом —
|
||||
теперь он шаг по ответу.
|
||||
|
||||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 8
|
||||
**Строки «отложено в `av-dev:code-deep-review`» перенеси дословно.** Их пишут
|
||||
проходы, упёршиеся в предел цикла: нужен замер, нужен прогнанный путь, нужен вход
|
||||
шире диффа. В цикле задачи это не доказывается ничем, а строки копятся и однажды
|
||||
становятся поводом позвать глубокое ревью области; пересказанные своими словами,
|
||||
они теряют оракул и перестают быть поводом.
|
||||
|
||||
**Сигнал «это изменение просит глубокого ревью»** приходит от `review-code` и
|
||||
подтверждается `review-basics`. Он не команда и не стоп — строка доклада: когда
|
||||
звать глубокий прогон, решает человек.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 6
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
нельзя — её написал тот, кто мог проход и пропустить.
|
||||
|
||||
### 8. Архивировать — `opsx:archive`
|
||||
### 6. Архивация и документы — отражение молча, новое по слову
|
||||
|
||||
Вызови Skill `opsx:archive`: change уезжает в архив, дельты вливаются в
|
||||
актуальные спеки. Не пропускай `openspec validate --strict` перед этим.
|
||||
Шаг идёт **в три такта**, и агент запускается в нём дважды. Причина одна: письмо
|
||||
в документы бывает двух родов, а спрашивается только один.
|
||||
|
||||
### 9. Синк документации
|
||||
**Копия.** Дом правила — раздел «Два рода правок» скилла `av-dev:doc-sync`.
|
||||
Правится дом, а не этот файл.
|
||||
|
||||
**Вызови Skill `av-dev:doc-sync`**: он владеет содержимым документов канона и
|
||||
ведёт чек-лист синка.
|
||||
<!-- копия: синк-род-правки из av-dev/skills/doc-sync/SKILL.md -->
|
||||
|
||||
**Правило одно и оно жёсткое: принуждённое отрицание.** Доклад обязан назвать
|
||||
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
|
||||
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
|
||||
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
|
||||
работает только обязательное отрицание.
|
||||
- **Отражение** — документ уже описывает эту вещь, и без правки он **станет
|
||||
ложным**: миграция написана, а `database.md` её не знает; компонент заведён, а
|
||||
`architecture.md` перечисляет прежние. Такая правка ничего не решает, она
|
||||
договаривает решённое на чекпоинте и уже стоящее в коде. **Пишется молча.**
|
||||
- **Новое** — в каноне заводится запись или норма, которой не было: ADR, правило
|
||||
в конвенциях, записка в `research/`, инвариант в `CLAUDE.md`, сдвиг периметра в
|
||||
`security.md`, граница в `passport.md`, дефект в журнале `review.md`. Такая
|
||||
запись переживёт задачу и свяжет следующие. **Пишется только по слову
|
||||
человека.**
|
||||
|
||||
<!-- /копия: синк-род-правки -->
|
||||
|
||||
#### Такт первый — агент: архив и отражение
|
||||
|
||||
**Оба скилла уходят одному агенту, и это один запуск** (SKILL.md, «Кто пишет»).
|
||||
Работа письменная от начала до конца: `opsx:archive` вливает дельты в актуальные
|
||||
спеки, `av-dev:doc-sync` идёт по чек-листу и пишет отражение, и обе правки — по
|
||||
чек-листам своих скиллов, а не по суждению оркестратора. Разнесённые по двум
|
||||
запускам, они стоили бы двух заданий, двух возвратов и паузы между ними — при
|
||||
том что второй читает ровно то, что оставил первый.
|
||||
|
||||
В задании: корень проекта, идентификатор change, база диффа и **порядок** —
|
||||
сначала `opsx:archive` с `openspec validate --strict` перед ним, затем
|
||||
`av-dev:doc-sync`.
|
||||
|
||||
**Вычитка и гейт идут последним тактом, в котором писали.** Вернул непустой
|
||||
список предложений — оба ждут третьего такта; список пуст — этот такт последний,
|
||||
и оба идут в нём. Гонять гейт дважды подряд по одному дереву незачем, а вычитывать
|
||||
пачку, которая сейчас пополнится, — тем более. Вычитку зовёт сам
|
||||
`av-dev:doc-sync` (агента `doc-wording` по пачке правленого), и правило живёт в
|
||||
том скилле; гейт до зелёного доводит агент, потому что красный гейт остановил бы
|
||||
коммит следующим шагом — документы у многих проектов он проверяет.
|
||||
|
||||
**Отложенное этим тактом обязано вернуться.** Оттого такт третий идёт **всякий
|
||||
раз, когда была реплика** — в том числе когда человек не одобрил ничего: на нём
|
||||
висят вычитка и гейт, которые первый такт с себя снял. Пропустить его на отказе
|
||||
значило бы уехать в коммит с невычитанной правкой и непрогнанным гейтом.
|
||||
|
||||
**Возврат — чек-лист, адреса тронутого, исход валидации, строка сигнала сверки и
|
||||
исход гейта, если он гонялся.**
|
||||
Чек-лист уезжает в доклад целиком, и переписывать его своими словами нельзя —
|
||||
это единственный след того, что каждый документ был назван.
|
||||
|
||||
**Правило, которое задаёт его форму, одно и оно жёсткое: принуждённое
|
||||
отрицание.** Против **каждого** документа канона стоит одно из трёх — чем он
|
||||
обновлён, что по нему предлагается, либо «не требуется, потому что…».
|
||||
Нетронутые группируются одной строкой с общей причиной. Список триггеров прозой
|
||||
уже проверен на живом проекте и дал 6 записей ADR на 43 изменения; работает
|
||||
только обязательное отрицание. **Требование стоит в задании агента** — без него
|
||||
возврат придёт перечнем тронутого, а тронутое без нетронутого не отличается от
|
||||
невыполненного шага.
|
||||
|
||||
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
|
||||
`av-dev:doc-sync`, и копия уже однажды разошлась с оригиналом, потеряв два
|
||||
@@ -382,7 +389,59 @@ flowchart TD
|
||||
задачу нельзя: документ, заведённый мимо канона, окажется вторым домом ровно
|
||||
тому, что канон потом заведёт своим.
|
||||
|
||||
### 10. Коммит
|
||||
#### Такт второй — одна реплика человеку на весь хвост
|
||||
|
||||
Покажи **одним списком** всё, что заводится нового:
|
||||
|
||||
- **предложения синка** — ADR, конвенция, записка в `research/`, инвариант,
|
||||
периметр, дефект в журнал. Каждое строкой: что заведём, куда и на каком
|
||||
основании;
|
||||
- **урожай ревью с шага 5** — отложенные находки, из которых получаются задачи:
|
||||
формулировка, оракул, откуда взялась.
|
||||
|
||||
Человек отвечает разом. **Нового нет — реплики нет**, и шаг кончился первым
|
||||
тактом; у большинства задач так и выходит.
|
||||
|
||||
**Реплика одна, и делить её нельзя.** Спросить про ADR на синке, а про задачи
|
||||
отдельно — значит взять с человека два переключения там, где решение одно: что из
|
||||
найденного этой задачей переживёт её. Ровно поэтому вопрос про урожай и перенесён
|
||||
сюда с шага 5.
|
||||
|
||||
**Спрашиваешь, а не советуешь по каждому пункту.** Основание уже названо строкой,
|
||||
и второй абзац уговоров превращает реплику в чтение. Человек вправе ответить
|
||||
«ничего» — это исход, а не потеря: находки остаются строками доклада.
|
||||
|
||||
#### Такт третий — задачи оркестратором, документы агентом
|
||||
|
||||
**Идёт всякий раз, когда была реплика**, и порядок в нём жёсткий.
|
||||
|
||||
**Сначала задачи — их заводишь ты, а не агент.** Человек сказал «заводим» — зови
|
||||
Skill `av-dev:task-track`, у него на этот вход отдельный сценарий «задачи из ревью
|
||||
и аудита»: своя нарезка, свой формат, свои правила дублей. Находка передаётся
|
||||
**дословно, вместе с оракулом**. Согласован промоут находки в конвенцию — тем же
|
||||
вызовом заводится **задача `chore` на механизацию правила**: шаг 2 промоута
|
||||
(конфиг линтера, сканер, приведение кода к зелёному) в хвост чужой задачи не
|
||||
помещается (`av-dev:code-review`, `references/promote.md`).
|
||||
|
||||
**Заведение задач агенту не отдаётся ни в одном сценарии** — по той же причине,
|
||||
по какой ему не отдаются коммит и закрытие: оно правит индексы учёта, а перечень
|
||||
работ ведёт человек. Правило и его дом — SKILL.md, «Кто пишет».
|
||||
|
||||
**Потом документы — их пишет тот же агент, что шёл тактом первым.** В задании:
|
||||
|
||||
- **одобренные записи дословно** — формулировка, источник, основание; сочинять
|
||||
заново нельзя, ADR цитирует решение из архивного `design.md`, а не пересказывает
|
||||
его. Человек не одобрил ничего — писать нечего, и это законный вход;
|
||||
- **вычитка** `doc-wording` по всей пачке правленого — и первого такта, и этого;
|
||||
- **гейт проекта до зелёного** после правок — он же увидит заведённые задачи,
|
||||
потому они и заводятся раньше.
|
||||
|
||||
**Отвергнутое не пишется никуда.** Ни в один документ, ни отдельной записью «от
|
||||
такого-то отказались»: журнала отвергнутого канон не держит, и заведение его
|
||||
здесь было бы ровно тем новым, которого человек только что не заказал. Отказ
|
||||
идёт строкой доклада.
|
||||
|
||||
### 7. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
@@ -392,14 +451,14 @@ flowchart TD
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 11. Закрыть задачу — **после коммита, не раньше**
|
||||
### 8. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 10 упадёт.
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 7 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev:task-track`, не ты) — это правки в рабочем
|
||||
@@ -427,9 +486,19 @@ change. Заводить запись задним числом, чтобы её
|
||||
- ссылка на архивный change и хеш коммита;
|
||||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||||
это доклад приёмщику, а не отметка «принято»;
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, откуда взялась);
|
||||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||||
запускались и что проверить было невозможно. Доклад без неё сообщает
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, откуда
|
||||
взялась) и **что человек по нему решил**: заведены задачи или список остался в
|
||||
докладе;
|
||||
- **что заведено нового в документах** — одобренное по именам записей, и **что
|
||||
предложено и отвергнуто**, тоже по именам. Отказ виден только здесь: в
|
||||
документы он не пишется;
|
||||
- **сигнал сверки** — строка синка о том, сколько задач сделано с прошлого
|
||||
прогона `av-dev:doc-healthcheck`, либо что сверки не было ни разу;
|
||||
- **сколько находок ушло инлайном и сколько развилкой** — числом. По нему видно,
|
||||
во что прогон обошёлся человеку;
|
||||
- **одна строка границ покрытия**: какой режим гонялся, какие проходы не
|
||||
запускались и что проверить было невозможно;
|
||||
- **отложенное в `av-dev:code-deep-review`** — дословно из отчёта, либо «нечего». Доклад без неё сообщает
|
||||
«проверено», не сообщая, что именно.
|
||||
|
||||
## Тонкости сценария
|
||||
@@ -438,15 +507,23 @@ change. Заводить запись задним числом, чтобы её
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Стиль правок — заточка под проект и конвенции, по размеру задачи, без
|
||||
улучшений заодно.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает разметчик **до того**, как ты
|
||||
написал код, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа.** Отложенные находки
|
||||
отдаются **списком**; превращает их в задачи `av-dev:task-track`, у него на
|
||||
этот вход отдельный сценарий «задачи из ревью и аудита». Каталога задач в
|
||||
проекте нет — урожай остаётся списком в докладе, и это говорится строкой.
|
||||
- **Пропустить тему или проскочить чекпоинт — самый дешёвый способ «ускориться»,
|
||||
и он же самый дорогой по последствиям.** Защита устроена так, что регулятора у
|
||||
тебя нет: состав прогона постоянный и сокращению не подлежит, перечень тем
|
||||
сверяется по исходу, непокрытое называется строкой, а расхождение с одобренным
|
||||
— отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью не идёт по умолчанию.** Отложенные находки
|
||||
отдаются **списком**, и в задачи их превращает `av-dev:task-track` — по слову
|
||||
человека и вызовом от тебя, а не от агента: перечень работ ведёт человек, а
|
||||
индексы учёта правит тот же, кто коммитит. У скилла на этот вход отдельный
|
||||
сценарий «задачи из ревью и аудита». Каталога задач в проекте нет — урожай
|
||||
остаётся списком в докладе, и это говорится строкой.
|
||||
- **Стопов у сценария два, и оба про решения человека, а не про ход работ.**
|
||||
Чекпоинт шага 3 решает форму решения **до** кода; реплика шага 6 решает, что из
|
||||
найденного переживёт задачу. Между ними прогон идёт сам: правки инлайном чинятся
|
||||
молча, отражение в документах пишется молча. Третьего стопа заводить нельзя —
|
||||
прогон, останавливающийся чаще, теряет ровно то время, ради которого короткие
|
||||
итерации и выбраны.
|
||||
- **Способ решения ты не выбираешь.** Он приходит известным: из постановки, из
|
||||
разведки, от человека. Выбор между двумя подходами с разной ценой делается в
|
||||
разведке, у своего чекпоинта, — не по ходу этого сценария.
|
||||
|
||||
+396
-568
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
state "проход в составе метки" as live
|
||||
state "проход в составе прогона" as live
|
||||
state "retune №1 — правка charter'а" as r1
|
||||
state "retune №2 — последняя попытка" as r2
|
||||
state "проход удалён" as dead
|
||||
@@ -79,7 +79,6 @@ stateDiagram-v2
|
||||
|
||||
| Проход | Класс дефекта для инъекции | Заготовка пробы |
|
||||
|---|---|---|
|
||||
| `review-scope` | пропущенная тема | положить в `docs/` новый документ и проверить, попал ли он в план темой |
|
||||
| `review-autotests` | отсутствующая верификация | убрать тест на изменённую ветку, оставить код рабочим |
|
||||
| `review-specs` | поведение вне спеки | добавить незаказанный фолбэк-дефолт на пустом входе |
|
||||
| `review-code` | нарушение прозаической конвенции | увести штатный отказ мимо единой точки трансляции ошибки |
|
||||
@@ -88,8 +87,9 @@ stateDiagram-v2
|
||||
| `review-basics` | отказ, видимый чтением | убрать обработку ошибки записи так, чтобы отказ считался успехом |
|
||||
| `review-basics` | своя тема проекта | нарушить правило из документа, у которого нет именного прохода |
|
||||
| `review-architecture` | второй способ | завести вторую точку генерации id мимо единой |
|
||||
| `review-code` | инвариант проекта | нарушить записанный в `CLAUDE.md` запрет по темам `security`, `operations` или `architecture` |
|
||||
| `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище |
|
||||
| `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле |
|
||||
| `review-ops` | ось времени | убрать обработку недоступности внешней зависимости в фоновом цикле |
|
||||
| `review-triage` | шум | подать 20 находок, из них 15 вкусовщина и 3 дубля — проверить потолок и дедуп |
|
||||
|
||||
Метрик сверх этого не заводим. Precision, корреляция между проходами, стоимость
|
||||
@@ -101,7 +101,7 @@ stateDiagram-v2
|
||||
|
||||
## Когда калибровать
|
||||
|
||||
- при заведении нового прохода — **до** включения в состав метки по умолчанию;
|
||||
- при заведении нового прохода — **до** включения в состав прогона;
|
||||
- при правке charter'а существующего — иначе непонятно, правка помогла или нет;
|
||||
- при появлении записи в журнале проскочивших дефектов — калибруем тот проход,
|
||||
который должен был поймать;
|
||||
|
||||
@@ -75,19 +75,23 @@ Severity — ось процесса; перечень осей — [shared/axes
|
||||
1. `Блокирует мердж` (≤3, каждая с оракулом);
|
||||
2. `Стоит исправить сейчас` (≤4);
|
||||
3. `Гипотезы без доказательства` — что понижено и почему;
|
||||
4. `Promote candidates` — кандидаты в конвенцию или правило линтера;
|
||||
5. `Границы покрытия` — сводная, обязательная.
|
||||
4. `Урожай` — реальные находки не для этого мерджа: формулировка, оракул,
|
||||
происхождение. Задачи из них заводит человек своим словом, не отчёт;
|
||||
5. `Отложено в av-dev:code-deep-review` — что доказывается только запуском,
|
||||
замером или входом шире диффа: тема, место, чем проверяется;
|
||||
6. `Promote candidates` — кандидаты в конвенцию или правило линтера;
|
||||
7. `Границы покрытия` — сводная, обязательная.
|
||||
|
||||
Перед секциями — сводка для человека: размер, сложность, метка и режим
|
||||
прогона, состояние гейта, **план разметки задачи с исходом по каждой теме**,
|
||||
сколько находок пришло на вход и сколько осталось.
|
||||
Перед секциями — сводка для человека: режим прогона, состояние гейта, **перечень
|
||||
тем с исходом по каждой**, сколько находок пришло на вход и сколько осталось,
|
||||
сколько из них помечено `инлайн` и сколько `развилка`.
|
||||
|
||||
**Реестр сводки — темы, а не проходы, и это не оформление.** Перечень запущенных
|
||||
проходов отвечает «все, кто должен был, отработали» и молчит о том, что именно
|
||||
осталось непроверенным: уехавший в старшую метку проход уносит тему с собой
|
||||
беззвучно. План же называет тему, её дом, глубину и исполнителя — и тема,
|
||||
осталось непроверенным: уехавший в другой скилл проход уносит тему с собой
|
||||
беззвучно. Перечень тем называет тему, её дом, глубину и исполнителя — и тема,
|
||||
оставшаяся без отчёта, видна сразу. Перечень проходов из сводки не исчезает, но
|
||||
идёт **внутри** плана, колонкой «кто закрывает».
|
||||
идёт **внутри** него, колонкой «кто закрывает».
|
||||
|
||||
Каждая находка в секциях 1–2 несёт дополнительное поле:
|
||||
|
||||
@@ -95,10 +99,12 @@ Severity — ось процесса; перечень осей — [shared/axes
|
||||
- Действие: инлайн | развилка
|
||||
```
|
||||
|
||||
`инлайн` — оркестратор чинит сам, не спрашивая и не логируя. `развилка` — цена
|
||||
исправления сопоставима с переработкой, либо выбор меняет scope, либо решение
|
||||
трогает инвариант: уезжает вопросом с вариантами и ценой каждого туда, где
|
||||
проект держит вопросы, а работа продолжается на остатке.
|
||||
`инлайн` — оркестратор чинит сам, не спрашивая и не логируя, **и это
|
||||
умолчание**. `развилка` — узкий выход с тремя основаниями: правка меняет
|
||||
дельта-спеки, находка сидит в необратимом месте (миграция, формат на диске,
|
||||
публичный контракт), находка трогает инвариант. Она уезжает вопросом с вариантами
|
||||
и ценой каждого туда, где проект держит вопросы, а работа продолжается на
|
||||
остатке.
|
||||
|
||||
Потребитель отчёта — оркестратор, который **реализует прочитанное**. Поэтому
|
||||
потолок в 7 пунктов — не забота о внимании читателя, а защита кодовой базы от
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
## Карта тем
|
||||
|
||||
**Дом бывает файлом или каталогом** — `docs/security.md` и `docs/security/`
|
||||
называют одну и ту же тему. Форму дома называет план разметки задачи; проход её не
|
||||
называют одну и ту же тему. Форму дома называет задание прохода; проход её не
|
||||
угадывает.
|
||||
|
||||
| Тема | Дом | Что оттуда берётся |
|
||||
@@ -34,10 +34,11 @@
|
||||
второй — `operations` и `requirements`; обе строки убраны, и цена этого названа в
|
||||
`SKILL.md`, раздел «Честный предел».
|
||||
|
||||
**Дом темы зависит ещё и от метки.** На `small` темы `security`, `operations` и
|
||||
`architecture` смотрятся не против домов из этой таблицы, а против **инвариантов
|
||||
`CLAUDE.md`**, и закрывает их `code`. Таблица описывает полный дом темы; сколько
|
||||
из него открыто на этом прогоне, говорит план разметки задачи.
|
||||
**Дом темы зависит от того, кто её закрывает.** В цикле задачи темы `security`,
|
||||
`operations` и `architecture` смотрятся не против домов из этой таблицы, а против
|
||||
**инвариантов `CLAUDE.md`**, и закрывает их `code`. Полные дома открывает скилл
|
||||
`av-dev:code-deep-review` своими проходами. Таблица описывает полный дом темы;
|
||||
что из него открыто на этом прогоне, говорит состав прогона.
|
||||
|
||||
Сквозное, не привязанное к теме:
|
||||
|
||||
@@ -45,12 +46,12 @@
|
||||
| --- | --- |
|
||||
| инварианты **с severity рядом с формулировкой** | `CLAUDE.md` (и `AGENTS.md`, если он рядом), раздел инвариантов |
|
||||
| что запускать запрещено, с путями; `testdata`; куда писать временное; имя основной ветки | `CLAUDE.md` |
|
||||
| типовые узлы, типовые ложноположительные, **вопросы по темам**, триггеры метки, недоступно проверке | `docs/review.*`, раздел настройки |
|
||||
| типовые узлы, типовые ложноположительные, **вопросы по темам**, недоступно проверке | `docs/review.*`, раздел настройки |
|
||||
| прецеденты: воспроизведённые дефекты с оракулом | `docs/review.*`, журнал |
|
||||
|
||||
**Вопросы проекта привязаны к теме, а не к имени прохода.** Раньше блок в
|
||||
`docs/review.md` адресовался поимённо (`ops: <вопрос>`), и когда проход уехал в
|
||||
старшую метку, вопрос перестал задаваться молча. Тема переезд прохода
|
||||
другой скилл, вопрос перестал задаваться молча. Тема переезд прохода
|
||||
переживает.
|
||||
|
||||
## Сшивать обязаны проходы
|
||||
@@ -65,7 +66,8 @@
|
||||
«запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась
|
||||
5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом
|
||||
занятости. **Число проход снимает сам, на этом прогоне**, настройки берёт из
|
||||
`docs/database.md`, и сшивают их `ops` и `adversary`. Раньше числа брались из
|
||||
`docs/database.md`, и сшивает их `ops` в глубоком ревью — в цикле задачи не
|
||||
снимает чисел никто. Раньше числа брались из
|
||||
`docs/research/`; теперь этот документ процессный, и замер неизвестной свежести
|
||||
больше не выдаёт себя за оракул.
|
||||
- **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там
|
||||
@@ -75,15 +77,16 @@
|
||||
**У `basics` стыков нет, и это не упущение.** Он не меряет, поэтому сшивать число
|
||||
с настройкой ему нечего; единственное его основание для `critical` — инвариант из
|
||||
`CLAUDE.md`, всё остальное он формулирует условиями и оставляет гипотезой. Его
|
||||
вход намеренно узкий: дома тем из плана плюс инварианты и журнал. Широкий вход —
|
||||
это метка `large`, и там он есть у `architecture`. Греп по базе ему разрешён
|
||||
вход намеренно узкий: дома тем из задания плюс инварианты и журнал. Широкий вход
|
||||
есть только у `architecture`, а он работает в глубоком ревью. Греп по базе ему разрешён
|
||||
точечный — «есть ли второй вызывающий», — но обход всей базы и инвентарь
|
||||
концепций не его работа.
|
||||
|
||||
**У `scope` стыков нет по другой причине: он не читает содержимого.** Его дело —
|
||||
найти дома и раздать темы, а не пересказать написанное. Пересказ сделал бы его
|
||||
посредником между документом и проходом, а посредник расходится с источником и при
|
||||
этом выглядит актуальным.
|
||||
**Дома передаются адресом, а не пересказом, и это правило пережило проход,
|
||||
который его исполнял.** Прежде темы раздавал `review-scope`: он находил дома и
|
||||
называл их путём с разделом, ничего не пересказывая. Прохода нет, состав
|
||||
постоянный, но правило то же — проход, получивший проинтерпретированный периметр,
|
||||
не заметит, что интерпретация неверна.
|
||||
|
||||
## Деградация — поразрядная
|
||||
|
||||
@@ -94,8 +97,9 @@
|
||||
|
||||
**Кто какой документ читает — из документа не выводится, а назначается планом.**
|
||||
Документ питает тему (это записано на стороне канона, таблица «Роли документов и
|
||||
темы ревью»), а тему на этом прогоне закрывает тот, кого назвала разметка задачи; вся
|
||||
раскладка «тема → проход → глубина» — в `SKILL.md` этого скилла и больше нигде.
|
||||
темы ревью»), а тему на этом прогоне закрывает тот, кто назван в составе прогона; вся
|
||||
раскладка «тема → кто закрывает → против чего» — в `SKILL.md` этого скилла и
|
||||
больше нигде.
|
||||
**Списка читателей не ведёт никто, и это не пробел.** Он жил бы на стороне
|
||||
канона, а документ живёт дольше, чем раскладка проходов: список разошёлся бы с
|
||||
конвейером молча и при этом выглядел актуальным. Однажды уже разошёлся.
|
||||
|
||||
@@ -52,6 +52,13 @@ flowchart TD
|
||||
тема относится к поведению системы, а не к тому, как мы пишем код, — это не
|
||||
конвенция, а требование: заводится дельта-спека обычным путём.
|
||||
|
||||
**Конвенция заводится по слову человека, и это не формальность.** Одна её строка
|
||||
становится входом каждого следующего прогона ревью и критерием для всех будущих
|
||||
задач — из всего, что пишет хвост задачи, конвенция связывает дальше всего.
|
||||
В цикле задачи она поэтому **предлагается**, а не заводится: строка предложения
|
||||
называет проверяемое свойство и проход, который его нашёл, и по этой паре человек
|
||||
решает (`av-dev:code-resolve`, `references/solve.md`, шаг 6, такт второй).
|
||||
|
||||
Промоут идёт **тем же путём, что change → spec**: правка попадает в тот же
|
||||
коммит, что и исправление кода, с пометкой в сообщении — история промоутов
|
||||
остаётся видна в `git log` по файлу конвенций.
|
||||
@@ -75,6 +82,12 @@ flowchart TD
|
||||
хук блокирует любой коммит, и правило снимут первым же раздражённым движением.
|
||||
Приводить код в соответствие — часть шага 2, отдельным коммитом.
|
||||
|
||||
**Отсюда и место шага 2: он не помещается в хвост чужой задачи.** Конфиг,
|
||||
сканер и приведение кода к зелёному — это работа размером с задачу, и сделанная
|
||||
попутно она удваивает прогон, который человек заводил ради другого. Согласованный
|
||||
промоут даёт **строку конвенции сейчас** и **задачу `chore` на механизацию**;
|
||||
задачу заводит `av-dev:task-track` тем же словом, что и саму конвенцию.
|
||||
|
||||
## Шаг 3. Удаление из конвенций и из промптов
|
||||
|
||||
**Шаг, который пропускают чаще всего, и единственный, ради которого затевались
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
и `docs/adr/`.
|
||||
|
||||
Отдельно сюда попадают **решения о составе прогонов**: перестали звать проход,
|
||||
понизили метку правилом, сузили класс проверяемого. Не потому, что это промах,
|
||||
переселили его в другой скилл, сузили класс проверяемого. Не потому, что это промах,
|
||||
а потому, что здесь лежит цена: если что-то теперь проскочит, первый вопрос —
|
||||
«не тот ли это класс, который мы перестали проверять».
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
что необратимо и какой шаг гейта красит безусловно → `CLAUDE.md`; периметр и
|
||||
недоверенный вход → `docs/security.*`. **Вопрос по теме**, если промах лечится
|
||||
не фактом, а заданным вопросом, → раздел «Вопросы по темам» того же
|
||||
`docs/review.*`; адресуй теме, а не имени прохода — проход уедет между
|
||||
метками, тема останется. Самый частый адрес и самый дешёвый. Прежде чем
|
||||
`docs/review.*`; адресуй теме, а не имени прохода — проход уедет в другой
|
||||
скилл, тема останется. Самый частый адрес и самый дешёвый. Прежде чем
|
||||
править charter, проверь, не хватит ли факта или вопроса: charter общий для
|
||||
всех проектов, документ — про этот.
|
||||
- **в конвенции или в правило линтера** — если свойство выражается
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
# Метки задачи — выбор, цена, доли
|
||||
|
||||
**Дом правила выбора метки.** Состав проходов по каждой метке, схема процесса и
|
||||
раздача тем живут в [SKILL.md](../SKILL.md) — там диспетчер, и на готовой задаче
|
||||
его достаточно. Здесь то, что читают, когда метку **выбирают, оспаривают или
|
||||
калибруют**.
|
||||
|
||||
Применяет правило `review-scope` при разметке задачи — не автор изменения. Сама
|
||||
матрица уехала в его устав **помеченной копией**, и дословность её держит
|
||||
`copies.py`, а не обещание: прежде здесь стояло «расходиться не вправе», и
|
||||
подкреплено это было ничем. Проза вокруг матрицы — отрицательный тест `small`,
|
||||
доли, цена — принадлежит месту и живёт только здесь.
|
||||
|
||||
## Правило выбора — две оси, а не один вопрос
|
||||
|
||||
**Оси две, они измеряют разное, и метка есть максимум по ним.**
|
||||
|
||||
<!-- дом: матрица-метки -->
|
||||
|
||||
| | **знакомое** — форму решения можно назвать до начала | **незнакомое** — форму предстоит нащупать по ходу |
|
||||
|---|---|---|
|
||||
| **малое** — один узел | `small` | `large` |
|
||||
| **среднее** — несколько узлов одного слоя | `medium` | `large` |
|
||||
| **крупное** — несколько слоёв, перенос ответственности, большой рефакторинг | `large` | `large` |
|
||||
|
||||
<!-- /дом: матрица-метки -->
|
||||
|
||||
**Метка — не синоним размера.** Совпадают они только в левом верхнем углу: малое
|
||||
**незнакомое** изменение получает `large`, трогая один узел. Поэтому в плане
|
||||
стоят три строки, а не одна: размер, сложность и метка — каждая со своим
|
||||
обоснованием. Проход, выведший объём диффа из метки, ошибётся ровно на этом
|
||||
случае — а он и есть самый опасный: незнакомая форма в одном узле течёт там, где
|
||||
её никто не ждёт.
|
||||
|
||||
**Размер** — про объём: сколько мест трогается. **Сложность** — про
|
||||
неизвестность: знаем ли мы форму решения заранее. Признак незнакомого простой и
|
||||
проверяемый: **перед работой нельзя назвать, какие узлы будут тронуты**.
|
||||
|
||||
Раньше обе оси были склеены в один вопрос «крупное **или** незнакомое?». Ответ
|
||||
получался тот же, но две вещи под одним именем не измеришь по отдельности, и
|
||||
потому разметка не могла сказать «изменение среднее, но совершенно знакомое» —
|
||||
а именно эта пара и есть рабочее умолчание. Теперь обе оси называются в плане
|
||||
поимённо, и обе — с обоснованием.
|
||||
|
||||
**Оси называются и на стадии дизайна, и на стадии кода — но считаются один
|
||||
раз.** Это и есть причина, по которой разметка переехала к `propose`: состав
|
||||
ревью дизайна выводится из той же пары, что и состав ревью кода, а считать её
|
||||
дважды значит один раз посчитать без разведённости с автором.
|
||||
|
||||
**Обратимость — не третья ось, а отрицательный тест.** Она не уточняет размер и
|
||||
не уточняет сложность: она запрещает нижнюю метку независимо от обеих.
|
||||
|
||||
**Отрицательный тест `small`, и он важнее положительного:** изменение, которое
|
||||
после мерджа **не откатывается обратной правкой**, — не `small`, каким бы
|
||||
маленьким ни был дифф. Сюда попадают миграция схемы и данных, формат на диске,
|
||||
публичный контракт, имя, которое разойдётся по кодовой базе. Три строки миграции
|
||||
— это `medium`, а не `small`: размер диффа и цена ошибки здесь расходятся.
|
||||
|
||||
Что здесь считается крупным, что — незнакомым и что — мелким, проект уточняет в
|
||||
`docs/review.md`, подразделе «Триггеры метки»: **тремя списками** — по одному на
|
||||
каждую ось вверх и один вниз, поимённо, узлами или capability. Это **уточнение**,
|
||||
а не отмена: не записано — работает таблица выше.
|
||||
|
||||
## Спорный случай решается вниз, и у этого есть цена
|
||||
|
||||
Правило асимметрично, потому что асимметрична цена ошибки.
|
||||
|
||||
- **Спорно между `medium` и `large` → бери `medium`.** Ошибка в эту сторону
|
||||
стоит находки, которая всплывёт на следующей задаче или в журнале дефектов.
|
||||
Ошибка в обратную стоит трёх тяжёлых проходов, двое из которых держат машину и
|
||||
идут цепочкой, — и платится она **на каждой** задаче, выбранной неверно.
|
||||
- **Спорно между `small` и `medium` → бери `medium`.** Раньше эта строка
|
||||
обосновывалась тем, что состав одинаков и ошибка почти бесплатна. Теперь состав
|
||||
разный, и обоснование стало прямо противоположным: на `small` три темы ядра
|
||||
смотрятся **только против записанных инвариантов**, а спорный случай — ровно тот,
|
||||
где неизвестно, покрыт ли он инвариантом. Сомнение здесь стоит дороже, чем
|
||||
раньше, и потому решается вниз тем более твёрдо.
|
||||
|
||||
**Выбор сделан в пользу пропускной способности, и это записано, а не подразумевается.**
|
||||
Конвейер настроен на поток задач, а не на максимум находок с каждой: поправить в
|
||||
следующей задаче дешевле, чем держать одну два часа. Отсюда три обязанности,
|
||||
без которых сделка превращается в незаметную потерю качества:
|
||||
|
||||
- **границы покрытия называют темы и их глубину**, а не только запущенные
|
||||
проходы — иначе `small` выглядит так же, как `large` без находок;
|
||||
- **журнал дефектов в `docs/review.md` перестаёт быть хорошей практикой и
|
||||
становится единственной обратной связью**: проскочивший дефект — единственный
|
||||
сигнал, что метка выбрана слишком низко;
|
||||
- **возврат в код — повод пересмотреть метку.** Задача, которая приходит в тот
|
||||
же узел третий раз, уже не мелкая, чем бы ни выглядел её дифф.
|
||||
|
||||
## Метка — максимум по поверхности
|
||||
|
||||
**Обе оси меряются по всему диффу разом, и максимум по каждой отвечает за весь
|
||||
дифф.** Метка изменения — не средневзвешенное: одна строка в перечне границ
|
||||
задачи поднимает метку всему остальному, включая ту часть, которая сама по себе
|
||||
была бы `small`.
|
||||
|
||||
Обратное тоже верно и тоже не бесплатно: у каждой задачи есть **несокращаемый
|
||||
костяк — гейт, спеки, код, триаж**. Разрезать задачу, обе половины которой
|
||||
остаются в одной метке, значит заплатить костяк дважды за ту же проверку.
|
||||
Резать стоит там, где разрез **снимает доказательство с большей части диффа**.
|
||||
Шов и правило нарезки живут у того, кто ведёт задачи, — скилл
|
||||
`av-dev:task-track`, его раздел о нарезке. Пути туда конвейер не выносит: за
|
||||
пределы своего скилла он ходит вызовом, а не файлом.
|
||||
|
||||
Разметка в костяк не входит — она платится один раз на задачу, а не один раз на
|
||||
прогон, и потому **разрез задачи её не удваивает**. Это единственное, что стало
|
||||
дешевле от переезда разметки к `propose`, и это же снимает прежний довод против
|
||||
нарезки.
|
||||
|
||||
**Размер, сложность, метка и глубина объявляются в отчёте, и все четыре с
|
||||
обоснованием.** Метка выбирает `review-scope`; он вправе и поднять, и понизить
|
||||
её — но не молча: строка «метка X, потому что размер Y и сложность Z»
|
||||
обязательна на каждом прогоне, а не только когда метка отличается от ожидаемой.
|
||||
|
||||
## Чем `small` дешевле `medium` и что это стоит
|
||||
|
||||
Экономят три рычага — непуск, вход, потолок, — и они общие для всех проходов и
|
||||
всех меток; их дом и точные числа в [SKILL.md](../SKILL.md), раздел «Модель по
|
||||
проходу». Здесь только то, что рычаги делают **с этой меткой**:
|
||||
|
||||
1. **Составом.** `basics` на `small` не запускается — кроме случая, когда у
|
||||
проекта есть свои темы; тогда он идёт **только с ними**, ровно как в `large`.
|
||||
Три темы ядра, которые он держал бы, переходят к `code` сверкой по
|
||||
инвариантам.
|
||||
2. **Входом.** На `small` `specs` читает только дельта-спеку, а `code` — только
|
||||
**индекс** конвенций (перечень родов и что механизировано), не весь их дом. На
|
||||
`medium` оба читают дома целиком.
|
||||
3. **Потолком.** На `small` потолки самые жёсткие из трёх меток, и каждый
|
||||
напечатан в границах покрытия своего прохода.
|
||||
|
||||
**Что `small` за это не проверяет, названо поимённо и обязано идти строкой в
|
||||
границы покрытия:** темы `security`, `operations` и `architecture` смотрятся
|
||||
только против **записанных инвариантов** `CLAUDE.md`. Свойство, которого в
|
||||
инвариантах нет, с этой меткой не спросит никто — ни сценарием, ни чтением
|
||||
дома темы. Это и есть цена метки, и она заметно больше прежней: раньше `small`
|
||||
отличался от `medium` одним проходом на один вопрос, то есть не экономил
|
||||
ничего и назывался отдельной меткой зря.
|
||||
|
||||
**`large` назван по тому, что он добавляет: вход шире диффа.** Он единственный, где
|
||||
живут тяжёлые проходы, и единственный, где что-то **запускается**. `basics` в нём
|
||||
берёт только проектные темы; своих тем у проекта нет — он не запускается вовсе, и
|
||||
план говорит об этом строкой. **На `small` действует то же правило и по той же
|
||||
причине** — приёмник запускается только тогда, когда ему есть что принимать.
|
||||
Совпадение неслучайное: `basics` держит темы ядра ровно при одной метке из трёх,
|
||||
а приёмником проектных тем работает на всех.
|
||||
|
||||
## Доли — не пожелание, а проверка правила, и проверок две
|
||||
|
||||
**Сверху: `large` — 5–10%.** Если туда уходит каждая третья задача, метку
|
||||
выбирают по ощущению важности. Обратный перекос виден по журналу проскочивших
|
||||
дефектов: класс, который ловят только меряющие проходы, начинает всплывать после
|
||||
мерджа.
|
||||
|
||||
**Снизу: `small` не должен обгонять `medium`.** Ориентир — до трети задач, но
|
||||
сравнение важнее числа: **перевес `small` над `medium` значит, что рабочее
|
||||
умолчание сместилось, а решения об этом никто не принимал.** Проверка нужна
|
||||
именно теперь: пока две нижние метки совпадали составом, дрейф между ними не
|
||||
стоил ничего, и проверки не было. Сейчас он стоит трёх тем ядра, которые на
|
||||
`small` смотрятся только против инвариантов, — то есть ровно того, чем `small` и
|
||||
дёшев.
|
||||
|
||||
Считается это по журналу дефектов и по отчётам, а не по ощущению: метка
|
||||
напечатана в каждом отчёте, и посчитать её за месяц — работа на минуту.
|
||||
|
||||
**У дрейфа вниз есть свой стимул, и его стоит назвать.** `small` дешевле по
|
||||
времени и по деньгам, а выбирает метку хоть и не автор, но проход, читающий
|
||||
описание, написанное автором. Занижённое описание даёт занижённую метку без
|
||||
чьего-либо злого умысла — потому корректор и вынесен в `code`, который смотрит
|
||||
уже на код, а не на описание.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: doc-healthcheck
|
||||
description: "Проверка здоровья документации проекта судом, а не машиной: не разошлись ли документы между собой и с кодом. Зовёт двух агентов на весь канон разом — doc-consistency (один факт в двух домах, прямое противоречие, поведение в architecture.md вместо спек, ADR без парного статуса, число без происхождения) и doc-code-drift (протухший факт: имя ветки, команды, пути, зависимости поимённо, настройки с числом, единые точки, capability). Разбирает урожай порциями: строка на замену идёт в документ сразу, работа больше абзаца становится задачей. Использовать, когда с прошлой сверки сделан десяток задач, когда вернулись к проекту после перерыва, перед тем как опереться на документ в решении, а также шагом adopt и upgrade. Дорого — не на каждой задаче. Раскладку и версию раскладки проверяет скилл av-dev:canon, язык документов — агент doc-wording."
|
||||
description: "Проверка здоровья документации проекта судом, а не машиной: не разошлись ли документы между собой и с кодом. Зовёт двух агентов на весь канон разом — doc-consistency (один факт в двух домах, прямое противоречие, поведение в architecture.md вместо спек, ADR без парного статуса, число без происхождения) и doc-code-drift (протухший факт: имя ветки, команды, пути, зависимости поимённо, настройки с числом, единые точки, capability). Разбирает урожай порциями: строка на замену идёт в документ сразу, работа больше абзаца становится задачей. Прогон оставляет след — ключ [docs] healthcheck_last в .av-dev.toml, — и по нему синк документации считает, сколько задач сделано с прошлой сверки, и выдаёт сигнал строкой. Использовать, когда с прошлой сверки сделан десяток задач, когда вернулись к проекту после перерыва, перед тем как опереться на документ в решении, а также шагом adopt и upgrade. Дорого — не на каждой задаче. Раскладку и версию раскладки проверяет скилл av-dev:canon, язык документов — агент doc-wording."
|
||||
---
|
||||
|
||||
# Здоровье документации
|
||||
@@ -20,7 +20,10 @@ check` и его скрипт; здесь начинается там, где к
|
||||
- **с прошлой сверки сделан десяток задач.** Документы протухают ровно от
|
||||
сделанной работы: переименованная цель сборки, ушедшая зависимость, второй
|
||||
способ делать то, что обзор объявил единственным, факт, дописанный в
|
||||
`architecture.md` и уже живущий в `CLAUDE.md`;
|
||||
`architecture.md` и уже живущий в `CLAUDE.md`. **Этот признак считается, а не
|
||||
вспоминается**: счёт ведёт синк документации по следу прошлого прогона и
|
||||
выдаёт строкой на каждой сделанной задаче (`av-dev:doc-sync`, раздел «Сигнал
|
||||
сверки»);
|
||||
- **вернулись к проекту после перерыва** — прежде чем опираться на написанное;
|
||||
- **перед тем как опереться на документ в решении**, если оно дорогое;
|
||||
- шагом `adopt` и шагом `upgrade` — их зовёт скилл `canon` сам.
|
||||
@@ -123,6 +126,40 @@ check` и его скрипт; здесь начинается там, где к
|
||||
прогоне. Класс ошибок, который повторяется, идёт в `docs/review.*`, раздел
|
||||
настройки, — там дом типовых ложноположительных.
|
||||
|
||||
## След прогона
|
||||
|
||||
**Последним шагом прогон правит `.av-dev.toml`** — ключ `healthcheck_last` в
|
||||
секции `[docs]`: хеш коммита `HEAD` и дата комментарием рядом. Состав ключей —
|
||||
[канон](../canon/references/canon.md), раздел `.av-dev.toml`; правится **строка**,
|
||||
а не файл целиком.
|
||||
|
||||
**Секцию и имя ключа не выбирай сам.** Неизвестный ключ `.av-dev.toml` — отказ
|
||||
кодом 3, а не пропуск: ключ, заведённый мимо константы скрипта-владельца, роняет
|
||||
`docs.py`, `tasks.py` и гейт проекта разом. Этот ключ там уже назван
|
||||
(`DOCS_KEYS` в `av-dev/skills/canon/scripts/docs.py`), а любой другой пришлось бы
|
||||
заводить правкой скрипта.
|
||||
|
||||
**Без следа признак «десяток задач» не считается никем.** Так и было: сверку
|
||||
звали по памяти, то есть не звали — тот же прозаический триггер, что дал 6
|
||||
записей ADR на 43 изменения. След превращает признак в число, которое
|
||||
`av-dev:doc-sync` считает командой
|
||||
`git rev-list --count <last>..HEAD -- openspec/changes/archive` и говорит вслух
|
||||
на каждой задаче.
|
||||
|
||||
Ключ **необязательный и заводится сам** — первым же прогоном сверки; проекту для
|
||||
этого делать нечего. Его отсутствие значит «сверки не было ни разу», и синк
|
||||
говорит это отдельной строкой.
|
||||
|
||||
**Правку следа коммитит тот, кто позвал прогон.** Своего коммита у скилла нет:
|
||||
он правит документы, заводит задачи и ставит след — всё это уезжает одним
|
||||
коммитом разбора, и `last` в нём указывает на **прежний** `HEAD`, то есть на
|
||||
состояние, которое сверяли. Оставить правку незакоммиченной нельзя: счёт пойдёт
|
||||
от коммита, которого в истории нет.
|
||||
|
||||
**Позвал одного агента из двух — след всё равно ставится, но в докладе назван
|
||||
неполным.** Иначе следующая сверка отсчитывалась бы от прогона, который смотрел
|
||||
половину.
|
||||
|
||||
## Доклад
|
||||
|
||||
- **Кого позвал** — обоих или одного, и почему одного.
|
||||
@@ -139,11 +176,14 @@ check` и его скрипт; здесь начинается там, где к
|
||||
- **Не проверяет раскладку, версию и ссылки** — это `canon check`, там машина.
|
||||
- **Не судит язык** документов: залог, англицизмы, жаргон, термин без дома — это
|
||||
агент `doc-wording`, и зовут его отдельно, по пачке правленных документов.
|
||||
Звонящие у него названные — последний шаг синка в `av-dev:doc-sync`, шаг 9
|
||||
`av-dev:doc-init` и шаг вычитки в обоих режимах `canon`, — просто ни один из
|
||||
них не здесь. У него другой ритм: он нужен там, где текст только что писали, а
|
||||
Звонящие у него названные — последний заход синка в `av-dev:doc-sync`, шаг
|
||||
вычитки сценария разведки (`av-dev:code-resolve`), шаг 9 `av-dev:doc-init` и
|
||||
шаг вычитки в обоих режимах `canon`, — просто ни один из них не здесь. У него
|
||||
другой ритм: он нужен там, где текст только что писали, а
|
||||
не там, где он год лежал. Оркестровать его нечем — он один и работает по
|
||||
названному списку.
|
||||
- **Не правит документы за агентов** — они возвращают формулировки, решение
|
||||
подставить принимает человек или ты по его правилу.
|
||||
- **Не заводит задачи** — этим владеет `av-dev:task-track`.
|
||||
- **Не решает, когда себя звать.** Признак считает синк и говорит строкой; часы
|
||||
на прогон тратит человек своим словом.
|
||||
|
||||
@@ -123,7 +123,7 @@ description: "Завести новый проект — сессия вопро
|
||||
2. Проведи интервью итерациями по ≤3 вопроса.
|
||||
3. **OpenSpec — вызови Skill `av-dev:code-openspec`.** Он заводит каталог и
|
||||
заменяет пример в `config.yaml` настройкой. Делается это **до первого
|
||||
документа**: без `openspec/` не работают ни `opsx:propose`, ни ревью дизайна,
|
||||
документа**: без `openspec/` не работают ни `opsx:propose`,
|
||||
ни сверка требований. Каталог принадлежит конвейеру, а не канону, поэтому
|
||||
здесь только вызов — ни команды, ни формы файла `init` не знает.
|
||||
|
||||
|
||||
+155
-22
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: doc-sync
|
||||
description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md или из записки разведки, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл av-dev:canon.
|
||||
description: "Вести содержимое документов канона по ходу разработки. Правки двух родов, и спрашивается один: отражение сделанного (вливание дельт, миграция в database.md, компонент в architecture.md) пишется молча, а новая запись и новая норма (ADR, правило в conventions, записка в research, инвариант CLAUDE.md, периметр security.md, граница passport.md, дефект в review.md) только предлагается — пишет её второй запуск после слова человека. Построчный отчёт по каждому документу остаётся: каждый назван либо правкой, либо предложением, либо отрицанием с причиной. ADR и записка разведки — промоут цитатой из архивного design.md или записки, а не второе сочинение. Синк же считает и выдаёт строкой сигнал сверки: сколько задач сделано с прошлого прогона av-dev:doc-healthcheck, читая след в ключе [docs] healthcheck_last. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл av-dev:canon."
|
||||
---
|
||||
|
||||
# Ведение содержимого канона
|
||||
@@ -27,32 +27,84 @@ description: Вести содержимое документов канона
|
||||
Это тот же приём, что «границы покрытия» в отчёте ревью и «пустое называется
|
||||
пустым» в каноне.
|
||||
|
||||
## Два рода правок, и спрашивается один
|
||||
|
||||
Второе правило, поперёк первого: **пройти по всем документам обязан ты, а
|
||||
завести новое — человек**. Признак проверяемый и читается одним вопросом: **что
|
||||
станет с документом, если правку не сделать**.
|
||||
|
||||
<!-- дом: синк-род-правки -->
|
||||
|
||||
- **Отражение** — документ уже описывает эту вещь, и без правки он **станет
|
||||
ложным**: миграция написана, а `database.md` её не знает; компонент заведён, а
|
||||
`architecture.md` перечисляет прежние. Такая правка ничего не решает, она
|
||||
договаривает решённое на чекпоинте и уже стоящее в коде. **Пишется молча.**
|
||||
- **Новое** — в каноне заводится запись или норма, которой не было: ADR, правило
|
||||
в конвенциях, записка в `research/`, инвариант в `CLAUDE.md`, сдвиг периметра в
|
||||
`security.md`, граница в `passport.md`, дефект в журнале `review.md`. Такая
|
||||
запись переживёт задачу и свяжет следующие. **Пишется только по слову
|
||||
человека.**
|
||||
|
||||
<!-- /дом: синк-род-правки -->
|
||||
|
||||
**Показывается новое одной репликой и одним списком.** Каждый пункт — строкой:
|
||||
что заведём, куда и на каком основании. Человек отвечает разом, и одобренное
|
||||
пишет **следующий заход синка** — в цикле задачи это третий такт шага 6
|
||||
(`av-dev:code-resolve`, `references/solve.md`). **Нового нет — реплики нет**, и
|
||||
это обычный исход: у большинства задач хвост состоит из одного отражения.
|
||||
|
||||
**«По слову» — это по слову, а не вторым вопросом.** Человек уже сказал в этом
|
||||
прогоне «заведи ADR», сам решил сузить проверки, сам одобрил формулировку
|
||||
конвенции — слово сказано, и переспрашивать нечего: запись идёт как одобренная, а
|
||||
в докладе стоит, чьим решением. Предложение существует ради нового, которое
|
||||
заметил ты, а не ради ритуала.
|
||||
|
||||
**Отказ человека — строка доклада и всё.** В документы он не пишется: журнала
|
||||
отвергнутых ADR и снятых конвенций канон не держит, и заведение такого журнала
|
||||
здесь было бы ровно тем новым, которого никто не заказывал.
|
||||
|
||||
**Отрицание от этого не ослабло.** Документ, по которому нечего предложить,
|
||||
по-прежнему обязан быть назван — просто раньше отрицание читал отчёт, а теперь
|
||||
человек, и читает он его **до** того, как что-то написано. Обязанность та же:
|
||||
пропуск неотличим от «не требуется», пока отрицание не сказано вслух.
|
||||
|
||||
## Чек-лист синка
|
||||
|
||||
Идёт сверху вниз; каждая строка попадает в доклад.
|
||||
|
||||
| Документ | Обновляется, когда | Проверка |
|
||||
| --- | --- | --- |
|
||||
| `openspec/specs/` | всегда при изменении поведения | вливает `opsx:archive` |
|
||||
| `database.md` | тронуты миграции | `docs.py check --base` |
|
||||
| `architecture.md` | новый компонент, граница, внешняя зависимость, изменилось окружение | `docs.py`: capability без упоминания |
|
||||
| `adr/` | сработал триггер канона (перечень — [canon.md](../canon/references/canon.md#adr)) | нет — только этот чек-лист |
|
||||
| `research/` | узнали новое о внешнем формате или данных | нет |
|
||||
| `security.md` | новый недоверенный вход, токен, путь наружу, сдвиг периметра | нет |
|
||||
| `conventions/` | находка принята и не специфична для одного места | промоут |
|
||||
| `review.md` | дефект воспроизведён; сузили или расширили проверку | нет |
|
||||
| `passport.md` | новый потребитель, сдвиг границы «чем не является» | нет |
|
||||
| `CLAUDE.md` | изменился инвариант, гейт, запрет, необратимое | нет |
|
||||
| Документ | Род | Обновляется, когда | Проверка |
|
||||
| --- | --- | --- | --- |
|
||||
| `openspec/specs/` | отражение | всегда при изменении поведения | вливает `opsx:archive` |
|
||||
| `database.md` | отражение | тронуты миграции | `docs.py check --base` |
|
||||
| `architecture.md` | отражение | новый компонент, граница, внешняя зависимость, изменилось окружение | `docs.py`: capability без упоминания |
|
||||
| `adr/` | новое | сработал триггер канона (перечень — [canon.md](../canon/references/canon.md#adr)) | нет — только этот чек-лист |
|
||||
| `research/` | новое | узнали новое о внешнем формате или данных | нет |
|
||||
| `security.md` | новое | новый недоверенный вход, токен, путь наружу, сдвиг периметра | нет |
|
||||
| `conventions/` | новое | находка принята и не специфична для одного места | промоут |
|
||||
| `review.md` | новое | дефект воспроизведён; сузили или расширили проверку | нет |
|
||||
| `passport.md` | новое | новый потребитель, сдвиг границы «чем не является» | нет |
|
||||
| `CLAUDE.md` | новое | изменился инвариант, гейт, запрет, необратимое | нет |
|
||||
|
||||
**Разрез в таблице не произволен.** Ложным без правки становится ровно тот
|
||||
документ, который описывает **состояние системы**, — потому отражений в чек-листе
|
||||
и мало. Остальные задают норму или хранят память: им не с чем разойтись, пока в
|
||||
них не написано новое.
|
||||
|
||||
Пример доклада:
|
||||
|
||||
```
|
||||
Синк документации:
|
||||
Синк документации.
|
||||
Отражено, записано:
|
||||
- openspec/specs/ — влиты дельты change add-bucket-reindex
|
||||
- architecture.md — добавлен воркер свёртки, ссылка на capability reindex
|
||||
- database.md — миграция 00006, таблица bucket
|
||||
- adr/ — заведён ADR-2026-08-03-queue-as-table: отказ от внешней очереди
|
||||
- research/ — новое о формате не узнано
|
||||
- passport, security, conventions, review — не требуется: изменение внутреннее
|
||||
Предложено, жду слова:
|
||||
- adr/ — отказ от внешней очереди в пользу таблицы; источник: архивный
|
||||
design.md; триггер: намеренный отказ от очевидного подхода
|
||||
Не требуется: research, security, conventions, review, passport, CLAUDE.md —
|
||||
периметр не двигался, инварианты те же, новое о внешних данных не узнано.
|
||||
Сверка документов: с прошлой (a1b2c3d, 2026-07-30) сделано 11 задач — пора
|
||||
звать av-dev:doc-healthcheck.
|
||||
```
|
||||
|
||||
## Сверка — не здесь, а в `av-dev:doc-healthcheck`
|
||||
@@ -87,6 +139,14 @@ description: Вести содержимое документов канона
|
||||
она коснулась, — и назови этот список в промпте: по нему же он судит, известен ли
|
||||
термин. Находки он отдаёт готовыми формулировками, подставляешь их ты.
|
||||
|
||||
**Синк бывает в два захода, и вычитка идёт последним из них.** Вернул непустой
|
||||
список предложений — правка ещё не кончилась: человек ответит, и второй заход
|
||||
допишет одобренное. Вычитывать пачку, которая сейчас пополнится, значит платить
|
||||
за неё дважды. Значит: **предложения есть — вычитку откладываешь до второго
|
||||
захода; предложений нет — этот заход последний, и вычитка идёт в нём.** Отказ
|
||||
человека второго захода не отменяет: письма в нём не будет, а вычитка и гейт
|
||||
будут — иначе правка первого захода уедет в коммит невычитанной.
|
||||
|
||||
**Условие вызова — правка, а не синк.** Синк самый частый вызывающий, но не
|
||||
единственный: разведка (`av-dev:code-resolve`, сценарий разведки) пишет ответ по
|
||||
одному адресу и синком себя не считает намеренно — вычитка ей нужна ровно та же.
|
||||
@@ -118,9 +178,16 @@ description: Вести содержимое документов канона
|
||||
нет**. Строка «adr/ — не требуется: решение рутинное» и есть то, ради чего
|
||||
чек-лист существует; её отсутствие неотличимо от «забыл посмотреть».
|
||||
|
||||
Порядок работы: открой источник — архивный `design.md` change либо записку
|
||||
разведки, — найди в нём решение, проходящее триггер, процитируй его и причину,
|
||||
сошлись на источник, добавь строку в индекс `docs/adr/README.md` сверху.
|
||||
**Запись — новое, и заводится она по слову** (раздел «Два рода правок»).
|
||||
Сработавший триггер даёт не файл, а строку предложения: какое решение, из какого
|
||||
источника, каким из трёх триггеров прошло. Своей записи ADR не стоит ничего, а
|
||||
каталог решений читают как список того, что в проекте всерьёз, — и разбавленный
|
||||
рутиной он перестаёт им быть.
|
||||
|
||||
Порядок работы после «да»: открой источник — архивный `design.md` change либо
|
||||
записку разведки, — найди в нём решение, проходящее триггер, процитируй его и
|
||||
причину, сошлись на источник, добавь строку в индекс `docs/adr/README.md`
|
||||
сверху.
|
||||
|
||||
## Чистка `architecture.md`
|
||||
|
||||
@@ -197,8 +264,16 @@ av-dev:code-review`, его `references/review-journal.md`.
|
||||
|
||||
Твоя часть на синке: **дефект пишется сразу**, а не «потом, когда починим».
|
||||
Со временем теряется не факт, а то, почему дефект не поймали, — единственное,
|
||||
ради чего журнал есть. И решение сузить проверки (перестали звать проход, понизили
|
||||
метку) обязано попасть в раздел настройки, а не остаться в отчёте ревью.
|
||||
ради чего журнал есть.
|
||||
|
||||
«Сразу» и «по слову» здесь не спорят: запись — новое, и она идёт предложением, но
|
||||
**предложением этого прогона**, а не следующего. Отложить её до «когда починим»
|
||||
нельзя ни с чьего согласия: чинится дефект, а теряется причина промаха.
|
||||
|
||||
**Решение сузить проверки** (перестали звать проход, переселили его в другой
|
||||
скилл) обязано попасть в раздел настройки, а не остаться в отчёте ревью. Второй
|
||||
раз оно не спрашивается: такое решение принимает человек по определению, и слово
|
||||
по нему уже сказано — сказано тогда, когда проверку сузили.
|
||||
|
||||
## Промоут в конвенции
|
||||
|
||||
@@ -215,6 +290,61 @@ av-dev:code-review`, его `references/review-journal.md`.
|
||||
На синке это отдельная строка: «conventions/ — правило X механизировано,
|
||||
формулировка удалена» либо «не требуется».
|
||||
|
||||
**Конвенция — самое дорогое из нового, и на синке она только предлагается.**
|
||||
Одна её строка становится входом каждого следующего прогона ревью и критерием
|
||||
для всех будущих задач; находка, доехавшая до конвенции по инерции хвоста, потом
|
||||
годами разменивается на внимание прохода. Предложение называет **проверяемое
|
||||
свойство и проход, который его нашёл**, — по этой паре человек и решает.
|
||||
|
||||
**Шаг 2 в хвост задачи не помещается.** Механизация правила — конфиг линтера или
|
||||
сканер, плюс приведение кода к зелёному — это работа размером с задачу, и делать
|
||||
её попутно значит удваивать чужой прогон. Согласованный промоут даёт строку
|
||||
конвенции сейчас и **задачу типа `chore`** на механизацию — заводит её
|
||||
`av-dev:task-track`, и заводится она тем же словом человека, что и сама
|
||||
конвенция.
|
||||
|
||||
## Сигнал сверки — строка, а не вызов
|
||||
|
||||
Сверку документов (`av-dev:doc-healthcheck`) зовёт человек по признаку **«с
|
||||
прошлой сверки сделан десяток задач»**. Признак наблюдаемый, но считать его было
|
||||
нечем: следа у сверки не оставалось, и «десяток» держался в чьей-то памяти. Это
|
||||
ровно тот прозаический триггер, который дал 6 записей ADR на 43 изменения, — и
|
||||
здесь он не срабатывал по той же причине.
|
||||
|
||||
**След оставляет сама сверка** — ключ `healthcheck_last` в секции `[docs]`
|
||||
файла `.av-dev.toml` (состав ключей — [canon.md](../canon/references/canon.md),
|
||||
раздел `.av-dev.toml`). **Считает синк**, и вот чем:
|
||||
|
||||
```sh
|
||||
git rev-list --count <last>..HEAD -- openspec/changes/archive <каталог задач>
|
||||
```
|
||||
|
||||
Считаются коммиты, тронувшие **архив change или каталог задач** (его путь — ключ
|
||||
`[tasks] dir`). Оба пути выбраны потому, что доведённая до конца задача оставляет
|
||||
след хотя бы в одном: решение архивирует change, а обслуживание и разведка change
|
||||
не заводят вовсе и видны только закрытием — правкой индексов учёта. Считать один
|
||||
архив значило бы не считать `chore` и `research`, то есть на проекте с их
|
||||
перевесом говорить «звать рано» вечно.
|
||||
|
||||
Ни `openspec`, ни каталога задач в проекте нет — считай коммиты
|
||||
(`git rev-list --count <last>..HEAD`) и **скажи, что считал коммиты**: число
|
||||
другого рода, и молчаливая подмена сделала бы признак вдвое чувствительнее.
|
||||
Постановка, пришедшая текстом, следа не оставляет ни там ни там — такие задачи в
|
||||
счёт не входят, и это тоже говорится строкой, когда прогон шёл текстом.
|
||||
|
||||
Строка доклада обязательна всегда, и вариантов у неё три:
|
||||
|
||||
- **счёт меньше десятка** — «с прошлой сверки N задач, звать рано»;
|
||||
- **счёт от десятка** — «с прошлой сверки N задач, пора звать
|
||||
`av-dev:doc-healthcheck`»;
|
||||
- **ключа нет** — «сверка документов не проводилась ни разу», и это самый
|
||||
сильный из трёх сигналов, а не отсутствие данных.
|
||||
|
||||
**Сам не зовёшь.** Прогон сверки идёт по всему канону и держит `opus`; решение о
|
||||
таких часах принимает тот, кто их оплачивает. Синк, позвавший её сам, превратил
|
||||
бы самую дорогую проверку процесса в церемонию хвоста задачи — против чего она и
|
||||
вынесена в отдельный скилл.
|
||||
|
||||
## Чего этот скилл не делает
|
||||
|
||||
- **Не проверяет раскладку** — это `canon`.
|
||||
@@ -222,3 +352,6 @@ av-dev:code-review`, его `references/review-journal.md`.
|
||||
`doc-init`.
|
||||
- **Не сочиняет содержание.** Нечего записать — так и пишется, честной строкой.
|
||||
- **Не переоформляет документы «заодно»**: правится то, чего коснулась работа.
|
||||
- **Не заводит новое молча** — ни ADR, ни конвенцию, ни записку. Молча идёт
|
||||
только отражение, и признак у него один: без правки документ станет ложным.
|
||||
- **Не зовёт сверку документов** — считает и говорит строкой; зовёт человек.
|
||||
|
||||
@@ -244,20 +244,22 @@ stateDiagram-v2
|
||||
**напоминает** — беклог, заведённый до появления типа, законен, и переоформлять
|
||||
его «заодно» здесь не просят.
|
||||
|
||||
**Тип не выбирает метку ревью и глубину проверки.** Профиль выбирается по факту
|
||||
изменения, а не по типу задачи: `chore` бывает миграцией схемы, `fix` — правкой
|
||||
публичного контракта. Правило «предписание процесса в теле задачи снимается»
|
||||
типом не отменяется, а подтверждается: он описывает работу, а не то, как её
|
||||
проверять. **Стадия проекта их тоже не выбирает**: изменение на стройке ничем не
|
||||
проще того же изменения на доработке, и метку ему по-прежнему назначает разметка.
|
||||
**Тип не выбирает состав ревью и глубину проверки — и не выбирает их больше
|
||||
никто.** Состав прогона постоянный: он один и тот же на всякой задаче
|
||||
(`av-dev:code-review`, «Состав прогона»). Прежде состав считала метка `small` ·
|
||||
`medium` · `large`, и тогда эта строка отвечала на живой вопрос «не задаёт ли её
|
||||
тип»; метки нет, и вопрос снят вместе с ней. Правило «предписание процесса в теле
|
||||
задачи снимается» типом не отменяется, а подтверждается: он описывает работу, а
|
||||
не то, как её проверять. **Стадия проекта состава тоже не выбирает**: изменение
|
||||
на стройке ничем не проще того же изменения на доработке.
|
||||
|
||||
**Одно исполнителю тип всё же говорит — каким сценарием работу вести, и то не
|
||||
один.** Скилл `av-dev:code-resolve` выбирает сценарий связкой из двух
|
||||
признаков: тип **предлагает** (`chore` — обслуживание, `research` — разведка),
|
||||
а подтверждает его предмет работы — есть ли что менять в спеках. Признаки
|
||||
разошлись — работа останавливается, и тип меняется здесь, командой `edit --type`,
|
||||
а не переклеивается исполнителем по ходу. Метку и глубину это по-прежнему не
|
||||
задаёт: их называет разметка изменения, а на прогоне без change — сам сценарий.
|
||||
а не переклеивается исполнителем по ходу. Состава ревью это по-прежнему не
|
||||
задаёт: он постоянный, а на прогоне без change его называет сам сценарий.
|
||||
|
||||
## Как написана задача
|
||||
|
||||
@@ -567,9 +569,9 @@ python3 $tk adopt scan --from … --stage S | apply --plan … # разова
|
||||
**каждая давать видимую пользу**, а у штурма исход «выкинуть» — полноправный.
|
||||
|
||||
Там же **шов**: где резать, когда допустимых мест несколько. Коротко — по
|
||||
границе, которая одна поднимает метку ревью выше остальных; и не резать, когда
|
||||
обе половины остаются в одной метке, потому что несокращаемый костяк проверок
|
||||
платится за каждую задачу отдельно.
|
||||
границе, где **меняется род работы**; и резать пореже, потому что костяк ревью
|
||||
разрез удваивает **всегда** — состав прогона постоянный и от размера половин не
|
||||
зависит. Выигрыш даёт не проверка, а то, что половина доводится и мерджится сама.
|
||||
|
||||
### Вычитка: два прохода, а не один
|
||||
|
||||
@@ -633,9 +635,10 @@ python3 $tk adopt scan --from … --stage S | apply --plan … # разова
|
||||
- **свойство репозитория в рамках** — номер миграции, хеш, версия зависимости:
|
||||
в лежалой задаче протухает молча и становится ложной рамкой. Снимается;
|
||||
снимок берётся при постановке, а не при заведении;
|
||||
- **предписание процесса в теле** — «делать с такой-то меткой ревью», «взять
|
||||
такой-то агент»: это второй дом для правила выбора и путь понизить требования
|
||||
решением, принятым до проектирования. Снимается;
|
||||
- **предписание процесса в теле** — «прогнать глубоким ревью», «взять такой-то
|
||||
агент», «этой задаче хватит короткой проверки»: это второй дом для правила
|
||||
выбора и путь понизить требования решением, принятым до проектирования.
|
||||
Снимается;
|
||||
- **тип, разошедшийся с задачей** — задача заводилась починкой, а после разбора
|
||||
оказалось, что поведение никогда и не было заявлено: это `feature`, а не `fix`.
|
||||
Правится `edit <slug> --type …`; тип, оставшийся от прошлой формулировки, врёт
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
не файл-на-находку.** Если у ревью был триаж — половина работы уже сделана, бери
|
||||
его выход. Если нет — триажируй сам, прежде чем заводить.
|
||||
|
||||
**Штатный отправитель — `av-dev:code-review`** (и `av-dev:code-resolve`, который
|
||||
его вызывает): задач он не заводит сам, а отдаёт отложенные находки **списком
|
||||
урожая** — формулировка, оракул, откуда взялась — и хранит отчёт триажа вместе с
|
||||
изменением. Приходит и любой другой разбор, вплоть до пересказа человеком; тогда
|
||||
триажа нет и шаг 1 порядка делается руками.
|
||||
**Штатных отправителя два.** Первый — `av-dev:code-review` (и зовущий его
|
||||
`av-dev:code-resolve`): задач он не заводит сам, а отдаёт отложенные находки
|
||||
**списком урожая** — формулировка, оракул, откуда взялась — и хранит отчёт триажа
|
||||
вместе с изменением. Второй — `av-dev:code-deep-review`, и он зовёт этот сценарий
|
||||
напрямую, передавая согласованные с человеком находки дословно. Приходит и любой
|
||||
другой разбор, вплоть до пересказа человеком; тогда триажа нет и шаг 1 порядка
|
||||
делается руками.
|
||||
|
||||
## Находка агента — не задача
|
||||
|
||||
@@ -64,6 +66,14 @@
|
||||
ради которого заведение из ревью и выделено. Дешёвая мелочь по явному согласию может
|
||||
заводиться и без поштучного вопроса — но карта пользователю предъявляется
|
||||
всё равно.
|
||||
|
||||
**Барьер снимается ровно в одном случае — когда его уже прошли.** В хвосте
|
||||
задачи (`av-dev:code-resolve`, шаг 6; в обслуживании — шаг 5) человек одной
|
||||
репликой сказал, что из урожая заводится, и третьего стопа у прогона не будет:
|
||||
там карта идёт **строкой доклада**, а не вопросом. Признак читается буквально:
|
||||
**список находок уже был показан человеку и получил ответ**. Не был — карта
|
||||
предъявляется вопросом, и это обычный случай прямого вызова и вызова из
|
||||
`av-dev:code-deep-review`, где находки разбирались по одной, а нарезка — нет.
|
||||
6. **Заводи утверждённое** через `tasks.py add`, с тремя добавками:
|
||||
- **тег партии** — `--tag review-ГГГГ-ММ-ДД` (или `audit-<slug>`), чтобы весь
|
||||
заход разбора поднимался одной командой `list --tag …`;
|
||||
|
||||
@@ -30,25 +30,24 @@
|
||||
Тест выше говорит, **допустим** ли разрез. Где его провести из нескольких
|
||||
допустимых мест — отвечает шов.
|
||||
|
||||
**Шов — там, где падает метка ревью.** Раздел «Затрагивает» перечисляет
|
||||
границы; если одна строка перечня поднимает метку выше остальных, эта часть и
|
||||
режется отдельно. Пример: задача перекладывает несколько узлов разом и заодно
|
||||
добавляет два поля в существующий ответ. Целиком это `large` — полный состав проходов по
|
||||
всему диффу, включая те, что держат машину и идут цепочкой. Разрезанная по шву,
|
||||
она даёт `large` на маленькой переложенной части и `medium` на остатке.
|
||||
**Шов — там, где меняется род работы.** Раздел «Затрагивает» перечисляет
|
||||
границы; если одна строка перечня стоит особняком от остальных — трогает другой
|
||||
слой, переносит ответственность, вводит новое понятие, — эта часть и режется
|
||||
отдельно. Пример: задача перекладывает несколько узлов разом и заодно добавляет
|
||||
два поля в существующий ответ; переложенная часть и добавленные поля проверяются
|
||||
по-разному человеком, хотя конвейером — одинаково.
|
||||
|
||||
**Считай костяк, а не файлы.** У каждой задачи есть несокращаемые четыре прохода
|
||||
(гейт, спеки, код, триаж), и они платятся за каждую. Разрез, после которого обе
|
||||
половины остаются в одной метке, делает ревью **дороже**: тот же объём
|
||||
проверяется тем же составом, но костяк оплачен дважды. Отсюда правило: **резать,
|
||||
когда разрез снимает дорогой проход с большей части диффа**, и не резать, когда
|
||||
он просто делает файлы мельче.
|
||||
**Ревью на цену разреза больше не влияет.** Состав прогона постоянный: гейт,
|
||||
спеки, код, триаж плюс приёмник тем, — и каждая половина платит его целиком.
|
||||
Значит, разрез удваивает костяк ревью **всегда**, а не только когда обе половины
|
||||
остаются в одной метке; выигрыш он даёт не в проверке, а в том, что каждая
|
||||
половина доводится и мерджится сама по себе. Прежде здесь стояло правило «резать,
|
||||
когда разрез снимает дорогой проход с большей части диффа» — снимать больше
|
||||
нечего.
|
||||
|
||||
**Это планирование, а не предписание процесса.** Метка ревью выбирается по
|
||||
факту изменения — тем, кто его видит, — и в тело задачи не пишется: строка
|
||||
«делать с меткой medium» это ровно тот второй дом правила выбора, который
|
||||
гигиена полей снимает. Шов пользуется меткой как **признаком**, что в задаче
|
||||
две разнородные работы; решение о метке остаётся за конвейером.
|
||||
**Это планирование, а не предписание процесса.** Как проверять изменение, решает
|
||||
конвейер, увидев его; в тело задачи это не пишется — строка «делать вот так» и
|
||||
есть тот второй дом правила, который гигиена полей снимает.
|
||||
|
||||
## Что делать с родителем
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# 73. Гейт, прогнанный до ревью, не гоняется второй раз (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Гейт проекта прогонялся дважды на одном и том же дереве. Сценарий решения
|
||||
доводит его до зелёного шагом `opsx:apply`, сценарий обслуживания — своим шагом
|
||||
гейта; следом ступень автотестов конвейера запускала ту же команду заново.
|
||||
|
||||
Замер по прогонам в проекте transcriber 23 августа: ступень автотестов заняла 5
|
||||
минут 51 секунду при ревью кода в 62 минуты. Дерево между двумя прогонами не
|
||||
менялось ни разу — код писал агент, возвращал зелёный гейт, и до ревью его никто
|
||||
не трогал.
|
||||
|
||||
Повтор держался не на доводе, а на умолчании: проход запускает команду, потому
|
||||
что так написано в его уставе, и никто не спрашивал, откуда взялось дерево, на
|
||||
котором он её запускает.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р274. Гейт, прогнанный до ревью, второй раз не гоняется.** Переиспользуется
|
||||
**команда, а не проход**: тема `autotests` закрывается целиком — логи шагов
|
||||
проход читает сам, находки об отсутствующей верификации выдаёт как обычно. Дом
|
||||
правила — ступень 1 конвейера, `av-dev:code-review`.
|
||||
|
||||
**Р275. Признак — отпечаток рабочего дерева, и он проверяемый.** Отпечаток
|
||||
снимают дважды: тот, кто прогнал гейт, — сразу после прогона, проход — перед
|
||||
началом работы. Совпали — прогон засчитан, разошлись — проход гонит гейт сам.
|
||||
Команда живёт домом в ступени 1 и помеченной копией в уставе `review-autotests`;
|
||||
дословность держит `copies.py`, а не обещание.
|
||||
|
||||
**Р276. Это не отмена правила «возврату на слово не верят»
|
||||
([тема 72](72-writing-delegated-to-agents.md), Р270), и вот почему.** На слово
|
||||
здесь не верят никому: гейт — вывод инструмента, а не проза агента, логи шагов
|
||||
проход открывает сам, и отпечаток отвечает ровно на тот вопрос, который делает
|
||||
чужой прогон доказательством, — **относится ли этот вывод к этому дереву**.
|
||||
Правило Р270 запрещает верить пересказу; засчитывается же не пересказ, а
|
||||
воспроизводимый артефакт с проверенной привязкой.
|
||||
|
||||
**Р277. Отказ безопасен по построению.** Любое расхождение — отпечатки не
|
||||
совпали, отпечатка в задании нет, логи недоступны — ведёт к полному прогону, и
|
||||
проход не спрашивает разрешения. Лишний прогон стоит минут, засчитанный чужой —
|
||||
красноты, которой никто не увидел; асимметрия цены и задаёт направление отказа.
|
||||
|
||||
**Р278. Временный каталог из отпечатка выпадает сам.** `--exclude-standard`
|
||||
отбрасывает игнорируемое, а логи шагов гейт пишет туда же. Проект, держащий
|
||||
временный каталог под git, отпечатками не совпадёт никогда — и получит честный
|
||||
прогон вместо тихого засчитывания. Настройки у этого нет намеренно: выключатель
|
||||
здесь стал бы способом засчитать прогон, который засчитывать нельзя.
|
||||
|
||||
**Р279. Переиспользование объявляется строкой** — в сводке прохода и в границах
|
||||
покрытия: чем гейт прогнан, когда и на каком отпечатке. Молчащее
|
||||
переиспользование неотличимо от собственного прогона, а разница между ними в том,
|
||||
кто видел вывод своими глазами.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С254. Возврат агента письма пополнился отпечатком.** К исходу гейта и тому, чем
|
||||
он прогнан ([тема 72](72-writing-delegated-to-agents.md), Р269), добавились путь к
|
||||
логам шагов и отпечаток дерева. Возврат от этого не удлинился на экран: обе вещи
|
||||
— строки, а не содержимое.
|
||||
|
||||
**С255. Оркестратор передаёт исход гейта в ревью.** Шаг 7 решения и шаг 4
|
||||
обслуживания несут его вместе с планом, базой диффа и режимом. Не передал —
|
||||
конвейер прогонит гейт сам, и это стоит минут, а не корректности.
|
||||
|
||||
**С256. Экономия названа замером, а не обещанием.** Снятый повтор — минуты одного
|
||||
прогона из шестидесяти двух; остальное время ревью держат проход враждебных
|
||||
постановок, цепочка за машину и триаж, и они разбираются отдельно.
|
||||
@@ -0,0 +1,74 @@
|
||||
# 74. Ревью дизайна снято, разметка переехала за код (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Сценарий решения шёл так: `propose` → разметка → ревью дизайна → чекпоинт →
|
||||
`apply` → ревью кода. Разметка считала метку по написанному о задаче, а стадия
|
||||
ревью дизайна смотрела предложение до кода: `specs` на каждой задаче, `rubric` с
|
||||
`medium`, `architecture` с `large`.
|
||||
|
||||
Замер по прогонам в проекте transcriber 22–23 августа: полный прогон сценария
|
||||
занимал 3 часа 20 минут машинного времени, из них разметка и ревью дизайна с
|
||||
отработкой находок — 30 минут, а повторная разметка с повторным архитектурным
|
||||
проходом после чекпоинта — ещё 15. Владелец назвал целью час на прогон.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р280. Стадия ревью дизайна снята целиком.** Ни `specs`, ни `rubric`, ни
|
||||
`architecture` на предложении не запускаются. Требования сверяет `specs` на
|
||||
готовом коде — тот же проход, тот же дом темы, другой момент.
|
||||
|
||||
**Р281. Разметка переехала за `apply`.** `review-scope` идёт после того, как код
|
||||
написан и гейт зелёный, и до первой ступени прогона. Величина по-прежнему
|
||||
считается один раз на задачу: перезапуск прогона по находке «переделать форму»
|
||||
разметку не повторяет.
|
||||
|
||||
**Р282. Размер меряется по диффу, сложность — по написанному о задаче.** Дифф
|
||||
отвечает «сколько мест тронуто на самом деле» и ничего не обещает; на вопрос
|
||||
«знали ли форму решения заранее» он не отвечает вовсе — по готовому коду не
|
||||
видно, нащупывали его или писали по образцу. Признак незнакомого стал
|
||||
проверяемым: **обещанные границы задачи сверяются с тронутыми**, разошлись
|
||||
поимённо — формы не знали.
|
||||
|
||||
**Р283. Правило «метка не пересматривается по факту диффа» снято.** Оно
|
||||
существовало ровно потому, что разметка шла до кода: пересмотр означал бы второй
|
||||
запуск разметчика. Теперь дифф — вход разметки, а не повод её оспорить, и
|
||||
пересматривать внутри прогона нечего: второй запуск на том же дереве вернёт то
|
||||
же самое.
|
||||
|
||||
**Р284. Чекпоинт остался и переехал к предложению.** Он стоит сразу после
|
||||
`propose` и до кода. Прежде он стоял после ревью дизайна намеренно — человек
|
||||
читал объяснение, уже просеянное машиной; теперь просеивать нечем, и это прямая
|
||||
цена решения. Взамен стоп пришёл раньше: коррекция здесь стоит правки спеки, а не
|
||||
переписывания готового кода.
|
||||
|
||||
**Р285. `review-rubric` осиротел, и это сказано в его уставе.** Проход жил только
|
||||
на снятой стадии: рубрика, составленная при видимом коде, подстраивается под
|
||||
увиденное, а судить код по критерию, под который он писался, — корреляция по
|
||||
построению. Устав остаётся рабочим для прямого вызова человеком; конвейер его не
|
||||
зовёт.
|
||||
|
||||
**Р286. Приёмочные критерии приходят только от постановки и с чекпоинта.**
|
||||
Раньше третьим источником была рубрика, уезжавшая в `tasks.md`. Слот в скелете
|
||||
`openspec/config.yaml` снят вместе с ней.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С257. Архитектурная находка теперь стоит переписывания.** Довод «та же находка
|
||||
на предложении стоит абзаца» был основанием стадии, и он остаётся верным — просто
|
||||
конвейер за него больше не платит. `architecture` работает по коду и только с
|
||||
меткой `large`; что этот класс сузился, идёт строкой в границы покрытия каждого
|
||||
прогона.
|
||||
|
||||
**С258. Разведённость выбора метки сохранена, а её основание сменилось.** Прежде
|
||||
метка выбиралась **до** кода, и давление «я почти закончил» на неё не действовало
|
||||
по построению. Теперь защита держится только на том, что метку называет не автор:
|
||||
разметчик работу не писал и обе оси выводит из фактов.
|
||||
|
||||
**С259. Разрез задачи снова удваивает разметку.** У каждой половины свой дифф, и
|
||||
мерить его приходится порознь; прежний довод «разметка платится один раз на
|
||||
задачу, и разрез её не удваивает» верен теперь только для перезапуска прогона.
|
||||
|
||||
**С260. Стадий у ревью больше нет — есть ступени.** Слово «стадия» в конвейере
|
||||
означало членение, видное снаружи; оно исчезло вместе со второй стадией, и проза
|
||||
приведена к «ступени».
|
||||
@@ -0,0 +1,60 @@
|
||||
# 75. Хвост задачи — один агент: архивация и синк вместе (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Хвост сценария решения шёл четырьмя вызовами подряд: `opsx:archive`,
|
||||
`av-dev:doc-sync`, `av-dev-git:commit`, `av-dev:task-track`. Первые два —
|
||||
письменная работа, и оба уже уходили агентам ([тема 72](72-writing-delegated-to-agents.md)),
|
||||
но **разными запусками**: два задания, два возврата и пауза оркестратора между
|
||||
ними.
|
||||
|
||||
Замер по прогонам в проекте transcriber 22–23 августа: архивация 5 минут, синк
|
||||
документации 14 минут, паузы оркестратора между шагами хвоста — около 3 минут на
|
||||
прогон. В соседней сессии те же два шага, отданные одному агенту, заняли один
|
||||
запуск на 29 минут вместо двух.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р287. Архивация и синк уходят одному агенту, одним запуском.** Второй шаг
|
||||
читает ровно то, что оставил первый: `opsx:archive` вливает дельты в актуальные
|
||||
спеки, `av-dev:doc-sync` сверяет с ними документы канона. Разнесённые по двум
|
||||
заданиям, они дважды платят за сбор одного и того же контекста.
|
||||
|
||||
**Р288. Порядок внутри задания назван, а не выведен.** Сначала `opsx:archive` с
|
||||
`openspec validate --strict` перед ним, затем `av-dev:doc-sync`. Синк по
|
||||
неархивированному change сверял бы документы с дельтами, которых в актуальных
|
||||
спеках ещё нет.
|
||||
|
||||
**Р289. Гейт после правок документов доводит до зелёного тот же агент.** Многие
|
||||
проекты проверяют документы гейтом, и красный гейт остановил бы коммит следующим
|
||||
шагом — то есть отказ обнаружился бы у оркестратора, которому чинить его нечем
|
||||
без второго задания.
|
||||
|
||||
**Р290. Коммит и закрытие задачи агенту не отдаются ни в одном сценарии.**
|
||||
Закрытие удаляет запись задачи и правит индексы, коммит уезжает в историю — оба
|
||||
необратимы для учёта. Оркестратор делает их сам, уже сверив план прогона с
|
||||
исходом; правило необратимого ([тема 72](72-writing-delegated-to-agents.md), Р268)
|
||||
остаётся в силе целиком.
|
||||
|
||||
**Р291. Чек-лист синка — единственное исключение из «возврат не длиннее экрана»**
|
||||
([тема 72](72-writing-delegated-to-agents.md), Р269). Он приходит целиком и целиком
|
||||
уезжает в доклад: тронутые документы поимённо, нетронутые — одной строкой с общей
|
||||
причиной. Сжатый своими словами, он теряет принуждённое отрицание, ради которого
|
||||
шаг и существует.
|
||||
|
||||
**Р292. В обслуживании синк тоже уходит агенту.** Там он главный шаг сценария и
|
||||
идёт без архивации — change у обслуживания нет по построению.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С261. Требование принуждённого отрицания переехало в задание.** Раньше оно
|
||||
адресовалось оркестратору, который звал `doc-sync` сам; теперь его обязан нести
|
||||
текст задания — иначе возврат придёт перечнем тронутого, а тронутое без
|
||||
нетронутого неотличимо от невыполненного шага.
|
||||
|
||||
**С262. Вычитку языка отдельным запуском больше не зовут.** `av-dev:doc-sync`
|
||||
зовёт `doc-wording` сам, по пачке правленых документов; в задании она не
|
||||
называется, потому что правило живёт в том скилле.
|
||||
|
||||
**С263. Шагов в сценарии решения стало девять.** Архивация и синк слились в
|
||||
седьмой; коммит стал восьмым, закрытие задачи — девятым.
|
||||
@@ -0,0 +1,82 @@
|
||||
# 76. Лёгкий проход в цикле, тяжёлые — в отдельном скилле (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
На метке `large` две темы закрывала пара тяжёлых проходов. `review-adversary`
|
||||
строил путь и **прогонял** падающий тест, `review-ops` снимал числа замером. Оба
|
||||
помечены «держит машину», а значит шли не разом, а цепочкой: второй ждал первого,
|
||||
и он же определял, когда стартует триаж.
|
||||
|
||||
Замер по прогону в проекте transcriber 23 августа: враждебный проход занял 25
|
||||
минут и держал весь параллельный залп, эксплуатационный — ещё 9 минут следом за
|
||||
ним. Ревью кода целиком заняло 62 минуты при цели в час на всю задачу.
|
||||
|
||||
Ценность пары при этом не оспаривается и измерена: на пяти задачах подряд
|
||||
враждебный дал пять из семи выживших находок дозапуска, эксплуатационный —
|
||||
единственный, кто нашёл, что откат бинаря поверх новой схемы стартует молча.
|
||||
Спорна не ценность, а **момент оплаты**: она платилась на каждой задаче с меткой
|
||||
`large`, а получалась на немногих.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р293. В цикле задачи обе темы закрывает один лёгкий проход `review-proof`.**
|
||||
`security` и `operations` разом, чтением и рассуждением: набросок пути (вход,
|
||||
преобразование, куда легло) и ось времени (миграция и откат, рост, удержание,
|
||||
чужая деградация). Потолки раздельные — 2 находки на тему: общий потолок дал бы
|
||||
одной теме съесть весь выход прохода.
|
||||
|
||||
**Р294. Он ничего не запускает, и потому машину не держит.** Отсюда главное для
|
||||
времени прогона: он уходит **в общем залпе** с остальными проходами, а не в
|
||||
цепочке за ресурс. Цепочки в обычном прогоне не осталось вовсе — оба прохода, что
|
||||
её держали, из конвейера ушли.
|
||||
|
||||
**Р295. `critical` этот проход не присваивает.** Оракул `critical` добывается
|
||||
запуском, а он не запускает; его потолок по severity — `major` с **названным**
|
||||
оракулом: чем это проверить, если кто-то возьмётся.
|
||||
|
||||
**Р296. Тяжёлая пара переехала в новый скилл `av-dev:code-deep-review`.** Не
|
||||
удалена: уставы сохранены целиком, сменились вход и вызывающий. Вход теперь —
|
||||
**названная человеком область кода** (модуль, слой, сервис), а не дифф задачи;
|
||||
метки здесь нет, потому что нет задачи; глубина постоянная — доказательство.
|
||||
|
||||
**Р297. Состав глубокого прогона постоянный:** `adversary`, `ops`,
|
||||
`architecture` на широком входе, `code` по коду целиком, сводит `triage`. Цепочка
|
||||
за машину там действует полностью — скилл идёт не на задаче, и часы у него есть.
|
||||
|
||||
**Р298. Исход глубокого прогона — разговор и задачи, а не правки.** Находки
|
||||
разбираются с человеком по одной, сверху вниз; по каждой он говорит «берём», «не
|
||||
берём» с причиной или «не находка». Согласованное уезжает задачами через
|
||||
`av-dev:task-track`, отвергнутое — строкой в журнал дефектов `docs/review.md`.
|
||||
Ни одной находки скилл не чинит сам: правка по ходу разбора превращает разговор
|
||||
в работу.
|
||||
|
||||
**Р299. Вход глубокому прогону копит сам цикл.** Всё, что доказывается только
|
||||
запуском, `review-proof` не выдаёт находкой и не выбрасывает: строка в границах
|
||||
покрытия называет тему, место и запуск. Строка переносится в доклад дословно и
|
||||
однажды становится поводом позвать глубокое ревью.
|
||||
|
||||
**Р300. Доказательства в цикле задачи нет ни на одной метке, и это сказано
|
||||
прямо.** Гонка, деградация под нагрузкой, исчерпание ресурса, откат бинаря поверх
|
||||
новой схемы — класс, который виден только построенным путём и снятым числом. На
|
||||
`large` его смотрит `proof` чтением и откладывает; ниже `large` не смотрит никто.
|
||||
Это самая крупная граница покрытия конвейера, и она идёт строкой каждого прогона.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С264. Глубин в конвейере стало две.** Сверка и разбор; доказательство —
|
||||
свойство глубокого прогона, и разметчик его не назначает: план с доказательством
|
||||
некому исполнить.
|
||||
|
||||
**С265. Цена ошибки метки вверх упала.** Прежде лишний `large` стоил трёх тяжёлых
|
||||
проходов, двое из которых держали машину; теперь — двух проходов чтением. Правило
|
||||
«спорное решается вниз» остаётся, но его обоснование стало слабее, и это
|
||||
записано.
|
||||
|
||||
**С266. Просрочку глубокого ревью видно по отчётам.** Если по одному месту в
|
||||
строках «отложено» повторяется один и тот же неснятый замер, дело не в метке —
|
||||
глубокий прогон просрочен. Это второй след рядом с журналом дефектов.
|
||||
|
||||
**С267. Тема пережила переезд прохода, и это проверка правила 0 конвейера.**
|
||||
`ops` ушёл, тема `operations` осталась и досталась `proof`. Ровно ради этого
|
||||
случая состав прогона и описывается таблицей «тема → глубина → кто закрывает», а
|
||||
не списком проходов.
|
||||
@@ -0,0 +1,120 @@
|
||||
# 77. Цикл задачи проверяет механику; метки сняты (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Тема 76 вынесла тяжёлые проходы в `av-dev:code-deep-review` и оставила в цикле
|
||||
лёгкий `review-proof`. Это сократило прогон, но не ответило на вопрос, **что
|
||||
именно цикл задачи обязан проверять**.
|
||||
|
||||
Владелец процесса назвал рамку прямо. Проекты — небольшие приложения для себя,
|
||||
без сложных доменов; агент в них **второй пилот и советник**, а за архитектурные
|
||||
решения отвечает человек; ценится срок задачи и короткие итерации, чтобы вовремя
|
||||
менять дизайн и требования. Отсюда два способа работы и разрез между ними:
|
||||
`av-dev:code-resolve` решает задачу быстро и в рамках существующих
|
||||
договорённостей, а `av-dev:code-deep-review` думает вдумчиво, обсуждает находки и
|
||||
заводит работы.
|
||||
|
||||
Конвейер этому разрезу не соответствовал в трёх местах.
|
||||
|
||||
**Цикл судил замысел.** На метке `large` шли `review-proof` (риск рассуждением) и
|
||||
`review-architecture` («не появился ли второй способ», «что опытный человек
|
||||
отсюда удалил бы»). Обе оптики дают находки, по которым решает человек, — то есть
|
||||
предмет глубокого ревью, а не быстрого прогона.
|
||||
|
||||
**Разметка стоила запуска, а решала всё меньше.** `review-scope` — отдельный
|
||||
агент на 404 строки, две оси, матрица, отрицательный тест, доли по журналу,
|
||||
справочник `review-levels.md` на 175 строк. Со снятой ступенью 4 метка правила
|
||||
только вход и потолки двух проходов.
|
||||
|
||||
**Хвост требовал человека там, где не должен.** Урожай отдавался
|
||||
`av-dev:task-track` как обязательный шаг: задачи заводились, а не предлагались.
|
||||
Правило разметки действий гласило «сомневаешься — ставь развилку», то есть
|
||||
умножало вопросы к человеку внутри прогона, который заведён ради скорости.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р301. Цикл задачи проверяет корректность и механику против записанного
|
||||
критерия.** Дельта-спеки, конвенции, инварианты `CLAUDE.md`, вывод инструментов.
|
||||
Вопрос «то ли это решение» в цикле не задаётся вовсе: у него два своих места —
|
||||
чекпоинт до кода, где форму одобряет человек, и скилл `av-dev:code-deep-review`,
|
||||
где находки разбирают по одной.
|
||||
|
||||
**Р302. Состав прогона постоянный, метки нет.** Гейт, `specs`, `code`, триаж;
|
||||
`basics` идёт тогда и только тогда, когда у проекта есть свои темы. Ось «метка»
|
||||
снята из `shared/axes.md`, справочник `review-levels.md` удалён, устав
|
||||
`review-scope` удалён.
|
||||
|
||||
**Р303. Ступень 4 ушла из цикла целиком.** `review-proof` упразднён, его устав
|
||||
удалён; `review-architecture` переехал в `av-dev:code-deep-review` вслед за
|
||||
`adversary` и `ops`. Прожил `proof` один день — с темы 76 до этой; он был
|
||||
правильным шагом в неверную сторону: облегчал проход, тему которого цикл вообще
|
||||
не должен разбирать.
|
||||
|
||||
**Р304. Темы `security`, `operations` и `architecture` в цикле закрывает `code`
|
||||
сверкой с записанными инвариантами, потолком 1 находка на три темы разом.**
|
||||
Свойства, которого нет в инвариантах, цикл не спросит. Это не «глубина ниже», а
|
||||
другой дом темы, и он называется строкой в каждом отчёте.
|
||||
|
||||
**Р305. Вход и потолки проходов стали постоянными.** `code` читает дом конвенций
|
||||
целиком, `specs` — дельту, актуальные спеки, `design.md`, `tasks.md`, паспорт и
|
||||
обзор архитектуры. Потолки: `code` — 4 конвенционных, 1 инвариантная, у
|
||||
технической половины потолка нет; `specs` — нет; `basics` — 4; триаж — 7.
|
||||
Обеим половинам потолка не ставят намеренно: пропуск дефекта и пропуск
|
||||
расхождения со спекой не оставляют следа нигде.
|
||||
|
||||
**Р306. Умолчание разметки действий — `инлайн`.** Прежнее правило «сомневаешься —
|
||||
развилка» перевёрнуто. Развилку получают три случая, и все названы: правка меняет
|
||||
**дельта-спеки**, находка сидит в **необратимом** месте, находка трогает
|
||||
**инвариант** `CLAUDE.md`.
|
||||
|
||||
**Р307. Задачи из урожая заводятся только по слову человека.** Список
|
||||
показывается одной репликой; сказал «заводим» — зовётся `av-dev:task-track`, не
|
||||
сказал — урожай остаётся строками доклада. Прежде вызов был обязательным шагом
|
||||
сценария.
|
||||
|
||||
**Р308. Отрицательный тест `small` заменён адресацией.** Изменение, которое после
|
||||
мерджа не откатывается обратной правкой, прежде поднимало метку; поднимать нечего,
|
||||
и признак теперь меняет **адресата находки** — она уходит человеку развилкой, а не
|
||||
чинится молча.
|
||||
|
||||
**Р309. Сигнал «метка занижена» стал сигналом «изменение просит глубокого
|
||||
ревью».** Признаки те же — несколько слоёв разом, нащупанная по ходу форма, новое
|
||||
понятие, необратимое место; адресат другой: человек, который решает, звать ли
|
||||
глубокий прогон. Носитель прежний — `review-code`, подтверждающий — `review-basics`.
|
||||
|
||||
**Р310. Строки «отложено в `av-dev:code-deep-review`» сводит триаж.** Пишут их
|
||||
проходы, упёршиеся в предел цикла; не сведённые в одну секцию, они растворяются
|
||||
по отчётам, и повод позвать глубокий прогон не копится нигде.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С268. Шагов в сценарии решения стало восемь.** Разметка ушла, нумерация
|
||||
сдвинулась: ревью кода теперь шаг 5, архивация с синком — 6, коммит — 7, закрытие
|
||||
— 8.
|
||||
|
||||
**С269. Чекпоинт стал единственным местом, где решается форма решения.** До этой
|
||||
темы у формы было два суждения — человека на чекпоинте и архитектурного прохода
|
||||
после кода. Осталось одно, и это записано прямо: одобренное на чекпоинте уезжает
|
||||
в код без второго суждения о замысле.
|
||||
|
||||
**С270. Ось времени в цикле не смотрит никто.** Обратима ли миграция, что станет
|
||||
с записями после отката, как узел ведёт себя через неделю роста — прежде эти
|
||||
вопросы задавал `basics` на метке `medium`. Развилка по необратимому месту
|
||||
адресатом их не заменяет: она срабатывает, только если находку кто-то сделал.
|
||||
Названо строкой «Честного предела», а не подразумевается.
|
||||
|
||||
**С271. Сверка состава подешевела.** Реестр тем был переменным — приезжал планом
|
||||
разметки и на каждой задаче выглядел иначе. Постоянный реестр сверяется взглядом:
|
||||
проходов пять, отчёт от каждого либо есть, либо назван непущенным.
|
||||
|
||||
**С272. Скелет `docs/review.md` потерял «Триггеры метки» и получил «Когда звать
|
||||
глубокое ревью».** Два списка вместо трёх: области, которые смотрят целиком, и
|
||||
что в этом проекте считается необратимым. Второй список работает и в цикле —
|
||||
им проверяется основание развилки.
|
||||
|
||||
**С273. Нарезка задач перестала опираться на метку.** Шов теперь ищется по роду
|
||||
работы, а не по тому, где падает метка; костяк ревью разрез удваивает **всегда**,
|
||||
и выигрыш даёт не проверка, а то, что половина доводится и мерджится сама.
|
||||
|
||||
**С274. Общий словарь канона с конвейером сузился до категорий и тем.** Имена
|
||||
меток из него ушли — вместе с самими метками.
|
||||
@@ -0,0 +1,112 @@
|
||||
# 78. Хвост задачи: отражение молча, новое — по слову (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Тема 77 привела ревью в соответствие с ролью агента: цикл проверяет корректность
|
||||
и механику, а суждение о замысле стоит там, где решает человек. **Хвост задачи
|
||||
остался прежним.**
|
||||
|
||||
Шаг 6 писал в документы сам. Синк шёл по чек-листу из десяти строк с
|
||||
принуждённым отрицанием и по сработавшему триггеру заводил ADR, промоутил находку
|
||||
в конвенцию, писал в `research/`, `security.md`, `CLAUDE.md`, журнал дефектов.
|
||||
Человек узнавал об этом **постфактум** — строками чек-листа в докладе, который
|
||||
читают последним и по диагонали. Задачи из урожая ревью к этому времени уже
|
||||
заводились по слову (Р307), а документы — нет: одна и та же работа, «что из
|
||||
найденного переживёт задачу», решалась в двух разных режимах.
|
||||
|
||||
Вопросов при этом выходило два — про урожай на шаге 5 и про документы на шаге 6,
|
||||
— то есть два переключения человека там, где решение одно.
|
||||
|
||||
Отдельно стояла **сверка документов**. `av-dev:doc-healthcheck` зовут по
|
||||
наблюдаемому признаку «с прошлой сверки сделан десяток задач», но следа сверка не
|
||||
оставляла и задачи с тех пор не считал никто. Это ровно тот прозаический триггер,
|
||||
измеренная цена которого записана в самом же синке: у ADR такой триггер дал **6
|
||||
записей на 43 изменения**.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р311. Правки в документы разделены по роду, и спрашивается один род.** Признак
|
||||
проверяемый: **что станет с документом, если правку не сделать**. Станет ложным —
|
||||
это **отражение**, и оно пишется молча. Появится запись или норма, которой не
|
||||
было, — это **новое**, и оно пишется только по слову человека.
|
||||
|
||||
**Р312. Отражение — документы, описывающие состояние системы.** Это
|
||||
`openspec/specs/`, `database.md` и `architecture.md`. Остальной чек-лист — новое:
|
||||
`adr/`, `conventions/`, `research/`, `security.md`, `passport.md`, `CLAUDE.md` и
|
||||
журнал `review.md` задают норму или хранят память, и разойтись им не с чем, пока
|
||||
в них не написано новое.
|
||||
|
||||
**Р313. Реплика человеку одна на весь хвост.** В ней и предложения синка, и
|
||||
урожай ревью; вопрос про урожай перенесён с шага 5 на шаг 6. Нового нет —
|
||||
реплики нет, и у большинства задач так и выходит.
|
||||
|
||||
**Р314. Шаг 6 идёт в три такта, агент запускается в нём дважды.** Первый такт —
|
||||
`opsx:archive` и отражение; второй — реплика; третий — письмо одобренного и
|
||||
задачи из урожая. Вычитку `doc-wording` зовёт `av-dev:doc-sync` **последним
|
||||
тактом, в котором писал**: вернул непустой список предложений — вычитка ждёт
|
||||
третьего такта, список пуст — идёт в первом.
|
||||
|
||||
**Р315. Конвенция — самое дорогое из нового, и в хвосте она только
|
||||
предлагается.** Её строка становится входом каждого следующего прогона ревью.
|
||||
Механизация правила (шаг 2 промоута: конфиг, сканер, приведение кода к зелёному)
|
||||
в хвост чужой задачи не помещается вовсе — это задача `chore`, заводимая тем же
|
||||
словом, что и сама конвенция.
|
||||
|
||||
**Р316. Отвергнутое не пишется никуда.** Ни в один документ, ни отдельной
|
||||
записью «от такого-то отказались»: журнала отвергнутого канон не держит, и
|
||||
заведение его было бы ровно тем новым, которого человек только что не заказал.
|
||||
Отказ идёт строкой доклада.
|
||||
|
||||
**Р317. «По слову» — это по слову, а не вторым вопросом.** Сказанное человеком в
|
||||
этом же прогоне повторно не спрашивается: решение сузить проверки принимает он по
|
||||
определению, ответ разведки одобрен чекпоинтом вариантов, прямая просьба «заведи
|
||||
ADR» и есть слово. Предложение существует ради нового, которое заметил агент.
|
||||
|
||||
**Р318. Сверка документов оставляет след, а синк его считает.** След — ключ
|
||||
`[healthcheck] last` в `.av-dev.toml`, хеш коммита прошлого прогона; ставит его
|
||||
`av-dev:doc-healthcheck` последним шагом. Счёт — `git rev-list --count
|
||||
<last>..HEAD -- openspec/changes/archive`, то есть в задачах, доехавших до архива;
|
||||
без openspec считаются коммиты, и это говорится вслух. Строка доклада
|
||||
обязательна всегда, вариантов три: рано, пора, не сверялись ни разу. **Синк
|
||||
сверку не зовёт** — часы на неё тратит тот, кто их оплачивает.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С275. Плановых стопов в сценарии решения два, и оба про решения человека.**
|
||||
Чекпоинт шага 3 решает форму решения до кода, реплика шага 6 — что из найденного
|
||||
переживёт задачу. Между ними прогон идёт сам: инлайн чинится молча, отражение
|
||||
пишется молча. Третий стоп заводить нельзя — прогон, останавливающийся чаще,
|
||||
теряет то время, ради которого выбраны короткие итерации.
|
||||
|
||||
**С276. Принуждённое отрицание сменило адресата, но не ослабло.** Каждый документ
|
||||
канона по-прежнему назван — правкой, предложением или отрицанием с причиной;
|
||||
изменилось то, что отрицание читает человек и читает его **до** того, как
|
||||
что-нибудь написано.
|
||||
|
||||
**С277. Сценарий обслуживания почти не спрашивает.** Он двигает факты — команды,
|
||||
шаги гейта, зависимости поимённо, пути, числа настроек, — а факт, разошедшийся с
|
||||
кодом, это отражение по определению. Поводов для реплики у него два: новый запрет
|
||||
в `CLAUDE.md` и сужение проверок в `review.*`, причём второе не спрашивается по
|
||||
Р317.
|
||||
|
||||
**С278. Признак «десяток задач» стал числом.** Ключ `.av-dev.toml`
|
||||
необязательный и заводится сам первым же прогоном сверки, поэтому версия
|
||||
раскладки не двигается и `upgrade` проектам не нужен. Отсутствие ключа читается
|
||||
однозначно: не сверялись ни разу.
|
||||
|
||||
**С279. Журнал дефектов теперь зависит от ответа человека.** Запись
|
||||
воспроизведённого дефекта — новое, и молчаливого «да» у неё больше нет. Правило
|
||||
«пишется сразу» сохранено в другом виде: предложение делается **этим** прогоном,
|
||||
отложить его до «когда починим» нельзя ни с чьего согласия. Но человек вправе
|
||||
отказать, и тогда калибровка конвейера по этому дефекту не состоится — цена
|
||||
названа здесь, а не подразумевается.
|
||||
|
||||
**С280. Отказ нигде не хранится, и похожее предложение придёт снова.** Это прямое
|
||||
следствие Р316 и сознательный размен: журнал отвергнутого сам стал бы каноном,
|
||||
который никто не заказывал. В `av-dev:code-deep-review` разбор устроен иначе —
|
||||
там отказ уезжает в `docs/review.md`, потому что прогон затевается ради разговора
|
||||
и его исход и есть артефакт.
|
||||
|
||||
**С281. Хвост подорожал только на задачах, где что-то заводится.** Второй запуск
|
||||
агента идёт лишь после непустой реплики; задача без нового кончается первым
|
||||
тактом, и по цене хвост у неё прежний.
|
||||
@@ -0,0 +1,58 @@
|
||||
# 79. След сверки переехал в секцию docs; ключ верхнего уровня ронял скрипты (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Тема 78 завела след сверки документов ключом `last` в секции `[healthcheck]`
|
||||
файла `.av-dev.toml`. Ревью трансформации — три прохода по скиллам и документам —
|
||||
нашло, что такого ключа не переживает ни один скрипт плагина.
|
||||
|
||||
Проверено запуском, а не рассуждением. В проекте с `[healthcheck] last` команда
|
||||
`docs.py check` печатает `ОТКАЗ: .av-dev.toml: неизвестные ключи верхнего уровня:
|
||||
healthcheck` и выходит кодом 3; `tasks.py check` — то же самое. Верхний уровень
|
||||
файла стережёт `shared/config.py` константой `TOP_KEYS`, и неизвестный ключ там —
|
||||
**отказ**, а не пропуск. То есть первый же прогон сверки сделал бы нерабочими
|
||||
`canon check/adopt/upgrade`, весь `task-track` вместе с закрытием задачи и гейт
|
||||
проекта, который их зовёт.
|
||||
|
||||
**Корень — не описка, а ложное обещание документа.** Раздел `.av-dev.toml` в
|
||||
каноне утверждал: «неизвестный ключ `docs.py` игнорирует». Утверждение было
|
||||
неверным и старше темы 78; при проектировании следа опёрлись на него и скрипт не
|
||||
открыли, хотя докстринг `check_keys` говорит прямо обратное: «неизвестный ключ —
|
||||
отказ, а не безмолвный пропуск».
|
||||
|
||||
## Решено
|
||||
|
||||
**Р319. След живёт ключом `healthcheck_last` в секции `[docs]`.** Секция досталась
|
||||
ему по смыслу: `[docs]` — настройки проверок документов, а сверка документов и
|
||||
есть такая проверка. Своя секция верхнего уровня стоила бы правки общего читателя
|
||||
`shared/config.py` и превратила бы файл, объявленный «версией и настройками», в
|
||||
хранилище состояния.
|
||||
|
||||
**Р320. Новый ключ `.av-dev.toml` заводится правкой константы скрипта-владельца,
|
||||
и только потом появляется в каноне.** Порядок именно такой, а не обратный:
|
||||
владелец ключа — тот скрипт, чья константа его перечисляет (`TOP_KEYS` в
|
||||
`shared/config.py`, `DOCS_KEYS` в `docs.py`, свой список в `tasks.py`).
|
||||
|
||||
**Р321. Канон приведён к скрипту, а не скрипт к канону.** Отказ кодом 3 —
|
||||
поведение верное: ключ, положенный не в ту секцию, при молчаливом пропуске не
|
||||
значит ничего, проверка объявляет себя неприменимой, отчёт выходит зелёным, и на
|
||||
месте настройки оказывается тишина. Ложное обещание снято, на его месте — правило
|
||||
Р320 и названная цена этой ошибки.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С282. Версия раскладки не двигается.** Ключ необязательный и заводится сам
|
||||
первым прогоном сверки; проекту делать нечего, а запись журнала версий нужна ради
|
||||
пункта «что сделать проекту».
|
||||
|
||||
**С283. Правило «своей прозе здесь верить нельзя» распространяется и на
|
||||
собственную документацию плагина.** Оно написано про возврат агента, но работает
|
||||
шире: утверждение документа о поведении скрипта проверяется **запуском скрипта**,
|
||||
и стоит эта проверка одной команды. Здесь её не сделали, и цена вышла в рабочую
|
||||
поломку у всякого, кто позвал бы сверку.
|
||||
|
||||
**С284. Гейт репозитория такого класса дефектов не ловит и ловить не может.** Он
|
||||
судит форму: фронтматтеры, дословность копий, адреса, номера журнала, рендер
|
||||
диаграмм. Согласованность прозы с поведением скрипта — суждение, и добыло его
|
||||
ревью, а не хук. Это довод в пользу того, чтобы прогон ревью по трансформации
|
||||
шёл не «если останется время», а следом за ней.
|
||||
@@ -0,0 +1,86 @@
|
||||
# 80. Противоречия хвоста сведены: кто зовёт учёт, когда идёт третий такт (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Тему 78 проверило ревью — три прохода по скиллам, документам и сквозной
|
||||
консистентности. Кроме поломки, разобранной темой 79, оно нашло, что тема
|
||||
противоречит сама себе в четырёх местах, и все четыре — про хвост задачи.
|
||||
|
||||
**Учёт отдали агенту, не сняв запрета.** Такт третий звал `av-dev:task-track`, а
|
||||
`code-resolve/SKILL.md` двумя абзацами ниже объявлял этот вызов оркестраторским и
|
||||
перечень закрытым, а границы задания агента прямо гласили «задач не заводит».
|
||||
|
||||
**Ветка отказа не была покрыта.** Первый такт откладывал вычитку и гейт в третий,
|
||||
третий запускался «только если человек что-то одобрил» — и на ответе «ничего»
|
||||
правка первого такта уезжала в коммит невычитанной, с непрогнанным гейтом.
|
||||
|
||||
**Дом правила вычитки не знал про два захода.** `doc-sync` велел звать
|
||||
`doc-wording` последним шагом правки; агент, читающий дом, вычитал бы половину
|
||||
пачки.
|
||||
|
||||
**Барьер учёта столкнулся с одной репликой.** Сценарий «задачи из ревью и аудита»
|
||||
требует показать карту кластеров через `AskUserQuestion` — изнутри агента, где
|
||||
показывать некому, и вторым вопросом там, где стоп уже был.
|
||||
|
||||
Отдельно разошёлся счёт стопов: «один плановый» в четырёх местах против «два» во
|
||||
фронтматтере и тонкостях, — и сценарий обслуживания получил реплику, но не
|
||||
получил того, кто пишет одобренное.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р322. Задачи из урожая заводит оркестратор, а не агент.** Довод тот же, что у
|
||||
коммита и закрытия: заведение правит индексы учёта, а перечень работ ведёт
|
||||
человек. Агенту третьего такта остаётся письмо в документы канона.
|
||||
|
||||
**Р323. Третий такт идёт всякий раз, когда была реплика** — в том числе на ответе
|
||||
«ничего»: на нём висят вычитка и гейт, снятые с себя первым тактом. Не
|
||||
запускается он ровно тогда, когда реплики не было вовсе.
|
||||
|
||||
**Р324. Дом правила вычитки знает про два захода.** Предложения есть — вычитка
|
||||
ждёт второго захода; предложений нет — заход последний, и вычитка идёт в нём;
|
||||
отказ человека второго захода не отменяет.
|
||||
|
||||
**Р325. Барьер карты кластеров снимается там, где его уже прошли.** Признак
|
||||
читается буквально: список находок уже показан человеку и получил ответ. Это
|
||||
хвост задачи; при прямом вызове и вызове из `av-dev:code-deep-review` карта
|
||||
по-прежнему предъявляется вопросом — там разбирали находки, а не нарезку.
|
||||
|
||||
**Р326. Стопов у сценария два, и счёт сведён в одну таблицу** — по сценариям, с
|
||||
разделением «до письма» и «после письма». Чекпоинт остаётся не более чем одним, и
|
||||
реплика этого счёта не касается: она решает не форму решения, а судьбу находок.
|
||||
|
||||
**Р327. У обслуживания появился второй заход, а повод для реплики один** — новый
|
||||
запрет или инвариант `CLAUDE.md`. Урожай ревью спрашивается той же репликой;
|
||||
сужение проверок не спрашивается вовсе, потому что его решил человек.
|
||||
|
||||
**Р328. Сигнал сверки считается по архиву change и каталогу задач разом.** Счёт
|
||||
по одному архиву не видел `chore` и `research`: они change не заводят и заметны
|
||||
только закрытием. Постановка текстом следа не оставляет ни там ни там — это
|
||||
говорится строкой.
|
||||
|
||||
**Р329. «Род правки документа» внесён в перечень осей** — отражение · новое, дом
|
||||
`av-dev:doc-sync`. Перечень объявлен полным, а ось ветвит поведение трёх скиллов;
|
||||
её отсутствие было ровно тем молчаливым пропуском, от которого перечень
|
||||
предостерегает в своей же шапке.
|
||||
|
||||
**Р330. Глубокое ревью пишет след в `docs/review.md` без второго вопроса.**
|
||||
`review.md` — документ рода «новое», но слово по каждой находке человек сказал в
|
||||
разборе, а след цитирует его решения.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С285. Сигнал сверки вошёл в контракт возврата и в доклады всех трёх
|
||||
сценариев.** Прежде строка была объявлена обязательной в скилле-владельце, но
|
||||
порождалась там, где её никто не обязан вернуть.
|
||||
|
||||
**С286. Прогон ревью после трансформации перестал быть необязательным.** Он нашёл
|
||||
одну рабочую поломку (тема 79) и четыре противоречия, ни одно из которых не видит
|
||||
гейт: гейт судит форму, а согласованность утверждений — суждение.
|
||||
|
||||
**С287. Часть находок ревью намеренно отложена, и это не пропуск.** Старший долг —
|
||||
основания развилки, названные то двумя, то тремя; `task-track/SKILL.md`, живущий
|
||||
в мире снятых меток; `review-basics`, у которого «нет тем ядра» и тут же есть
|
||||
`operations`; вопросы проекта по темам, обещанные проходам, которые о них не
|
||||
знают; расхождения `av-dev:code-deep-review` с уставами `review-code` и
|
||||
`review-triage`; отсутствующая запись журнала версий канона. Всё это старше темы
|
||||
78 и разбирается отдельным заходом.
|
||||
@@ -0,0 +1,78 @@
|
||||
# 81. Старший долг трансформации разобран: развилка, вопросы тем, версия 5 (2026-08-23)
|
||||
|
||||
## Что было
|
||||
|
||||
Тема 80 свела противоречия, внесённые темой 78, и назвала строкой С287 то, что
|
||||
осталось: находки ревью, которые старше трансформации хвоста и тянутся с тем 74–77.
|
||||
Этот заход разбирает их.
|
||||
|
||||
Долг был четырёх родов. **Перечень, разошедшийся с исполнителем**: конвейер
|
||||
называл два основания развилки, а устав триажа, контракт находок, сценарий решения
|
||||
и журнал — три. **Остатки снятого устройства**: `task-track/SKILL.md` объяснял, что
|
||||
метку назначает разметка, и искал шов по границе, «которая поднимает метку»;
|
||||
`config-skeleton.md` увозил в конфиг чужого проекта строку про «правило выбора
|
||||
метки». **Обещание без исполнителя**: конвейер обещал каждому проходу вопросы
|
||||
проекта по его темам, а три прохода из четырёх о вопросах не знали и места под
|
||||
ответ не имели. **Скилл, разошедшийся с уставами, которые он зовёт**:
|
||||
`av-dev:code-deep-review` назначал `review-code` глубину «доказательство» и отменял
|
||||
триажу потолок, ничего об этом уставам не сказав.
|
||||
|
||||
Отдельно стояла **непройденная миграция**: тема 77 переписала скелет
|
||||
`docs/review.md`, который уезжает в репозиторий проекта, а записи в журнале версий
|
||||
канона не появилось. Проекты, приведённые к версии 4, остались с подразделом
|
||||
«Триггеры метки» под словарь, которого больше нет.
|
||||
|
||||
## Решено
|
||||
|
||||
**Р331. Оснований у развилки три, и перечень сведён по всем местам.** Правка
|
||||
меняет дельта-спеки, находка сидит в необратимом месте, находка трогает инвариант
|
||||
`CLAUDE.md`. Там же названо, чем третье отличается: по первым двум оркестратор не
|
||||
останавливается, а урезает изменение до остатка; третье отменяет одобрение и
|
||||
**возвращает на чекпоинт**.
|
||||
|
||||
**Р332. Вопросы проекта по темам достались проходам, которые эти темы закрывают.**
|
||||
`review-code` (`conventions`, `security`, `operations`, `architecture`),
|
||||
`review-specs` (`requirements`) и `review-autotests` (`autotests`) получили
|
||||
обязанность отвечать дословно и строку в блоке покрытия. Задание вопросов не
|
||||
принесло — это говорится строкой: молча пропущенный вопрос неотличим от
|
||||
отвеченного, а других способов настроить проход под проект у проекта нет.
|
||||
|
||||
**Р333. Глубина в глубоком ревью — не одна на всех.** Доказательство дают те двое,
|
||||
что держат машину; `review-architecture` и `review-code` дают разбор на входе шире
|
||||
диффа, и выдать доказательство им нечем. `review-code` получил единственную
|
||||
оговорку про вызов оттуда: вход — область, потолков нет, машину он не держит и там.
|
||||
|
||||
**Р334. У триажа три вызывающих, а не два режима.** Прогон по change, прогон без
|
||||
change и глубокое ревью области, где перечень приходит составом прогона, а потолка
|
||||
в 7 пунктов нет: отчёт читает человек и разбирает находки по одной, поэтому вместо
|
||||
среза — порядок по убыванию ущерба.
|
||||
|
||||
**Р335. Версия раскладки поднята до 5.** Запись журнала называет, что переехало
|
||||
(подраздел «Триггеры метки» → «Когда звать глубокое ревью», двумя списками) и что
|
||||
сделать проекту: переписать подраздел, пройти по документам грепом, поднять
|
||||
версию, догнать `check`. Ключ `[docs] healthcheck_last` руками заводить не надо —
|
||||
он появится сам.
|
||||
|
||||
**Р336. Перечень осей досчитал три оси**, которые ветвили поведение годами:
|
||||
глубина темы, разметка действия, род правки документа. Каждая жила в своём скилле
|
||||
и оттуда была видна, а из перечня — нет; ровно за этим перечень и заведён.
|
||||
|
||||
## Следствия
|
||||
|
||||
**С288. След сверки коммитит тот, кто позвал прогон.** Своего коммита у
|
||||
`av-dev:doc-healthcheck` нет, и незакоммиченный след означал бы счёт от коммита,
|
||||
которого в истории не существует.
|
||||
|
||||
**С289. Проекты на версии 4 теперь видят дрейф.** `docs.py check` называет
|
||||
повышение прямо и зовёт `upgrade`; до этой темы расхождение скелета с каноном не
|
||||
замечала ни машина, ни человек.
|
||||
|
||||
**С290. Три прохода стали дороже ровно на то, что проект им скажет.** Вопросы по
|
||||
темам — механизм настройки, который до сих пор работал только у приёмника тем;
|
||||
пустой подраздел в `docs/review.*` ничего не стоит, а непустой перестал пропадать
|
||||
молча.
|
||||
|
||||
**С291. Ревью трансформации закрыто в три захода**, и цена его известна: одна
|
||||
рабочая поломка (тема 79), четыре противоречия внутри новой темы (тема 80) и
|
||||
двенадцать мест старшего долга (эта). Гейт не поймал ни одного: он судит форму, а
|
||||
всё перечисленное — согласованность утверждений.
|
||||
@@ -124,3 +124,12 @@
|
||||
| 70 | [«Провенанс» снят из словаря: одного синонима мало для проверки](70-provenance-word-removed.md) | 2026-08-13 |
|
||||
| 71 | [Образец языка назван прямо; «интейк» снят вслед за «провенансом»](71-language-model-popular-science.md) | 2026-08-13 |
|
||||
| 72 | [Письмо уходит агентам: оркестратор ставит задание и читает возврат](72-writing-delegated-to-agents.md) | 2026-08-22 |
|
||||
| 73 | [Гейт, прогнанный до ревью, не гоняется второй раз](73-gate-run-reused-by-fingerprint.md) | 2026-08-23 |
|
||||
| 74 | [Ревью дизайна снято, разметка переехала за код](74-design-review-dropped-scope-after-code.md) | 2026-08-23 |
|
||||
| 75 | [Хвост задачи — один агент: архивация и синк вместе](75-tail-in-one-agent.md) | 2026-08-23 |
|
||||
| 76 | [Лёгкий проход в цикле, тяжёлые — в отдельном скилле](76-proof-in-cycle-deep-review-apart.md) | 2026-08-23 |
|
||||
| 77 | [Цикл задачи проверяет механику; метки сняты](77-cycle-checks-mechanics-labels-dropped.md) | 2026-08-23 |
|
||||
| 78 | [Хвост задачи: отражение молча, новое — по слову](78-tail-reflection-silent-new-by-word.md) | 2026-08-23 |
|
||||
| 79 | [След сверки переехал в секцию docs; ключ верхнего уровня ронял скрипты](79-healthcheck-trace-moved-into-docs-section.md) | 2026-08-23 |
|
||||
| 80 | [Противоречия хвоста сведены: кто зовёт учёт, когда идёт третий такт](80-tail-contradictions-fixed.md) | 2026-08-23 |
|
||||
| 81 | [Старший долг трансформации разобран: развилка, вопросы тем, версия 5](81-elder-debt-of-transformation-cleared.md) | 2026-08-23 |
|
||||
|
||||
Reference in New Issue
Block a user