классификация задачи: три категории документов и метка вместо ступени
Канон 5 объявил «каждый документ docs/ — тема ревью». Правило верно ровно наполовину и потому вредно целиком. Паспорт и схему хранилища ревью читает, но темами они не являются: по ним нельзя сказать «в этом изменении сделано не так», они задают границу, по которой судит чужая тема. Журнал решений и журнал наблюдений ревью изменения не нужны вовсе — ADR объясняет прошлое, а не предъявляет требование. Разметчик, применявший правило буквально, обязан был либо завести фантомные темы passport, adr, database, research и продублировать ими работу architecture и operations, либо потерять четыре документа молча; случались обе ветки, и в собственном образце плана docs/passport.md не попадал ни строкой, а обязательная арифметика покрытия при этом не сходилась. Категорий теперь три, разрез проверяемый. Тема — да, прямо: conventions, security, architecture и любой свой документ проекта. Источник темы — нет, но он задаёт границу для чужой: passport, database, CLAUDE.md, openspec/specs. Процессный — нет, он про то, как мы работаем: tasks, review, adr, research, .pm.json. Открыта одна категория из трёх, две другие перечислены поимённо, так что документ вне раскладки — однозначно своя тема. adr и research прогон больше не открывает ни одним проходом; docs/review остаётся читаемым, но как настройка конвейера, а не критерий. Цена записана и стала обязательной строкой границ покрытия: расхождение с записанным решением ловит теперь только сверка документации, а число под находкой обязано быть снято на этом прогоне, с приложенной командой. Классификация выдаёт задаче метку — small, medium, large. Прежние quick, standard и wide назывались ступенью и описывали ревью: как глубоко смотрим. Классифицируется же задача, и пока величина называлась свойством прогона, её естественно было пересчитывать на каждом прогоне — что конвейер и делал. Слово «ступень» удалено, а не оставлено синонимом: два имени одной вещи расходятся. Выводится метка из двух разведённых осей — размер (малое, среднее, крупное) и сложность (знакомое, незнакомое), — и равна максимуму по ним. Метка не синоним размера: малое незнакомое изменение получает large, трогая один узел, поэтому план печатает три строки с обоснованием каждая и выводить одну из другой запрещено. Оси остались русскими словами — это суждение прозой; метка английская — это идентификатор, который проходы сравнивают. Разметка переехала из ревью кода в шаг 4 пайплайна, сразу после propose. Она шла первым проходом каждого ревью кода, а перед ревью дизайна ту же величину называл сам пайплайн — то есть оркестратор, который только что довёл предложение до propose. Одно и то же измерялось дважды, и один из двух раз без разведённости с автором, ровно в той точке, ради которой разметчик заведён. Теперь запуск один на задачу, диффа он не видит, план обслуживает обе стадии, и метка после кода не пересматривается: расхождение факта с разметкой ловит журнал дефектов постфактум, как и всякую другую ошибку выбора. На диск план не пишется — четвёртый артефакт рядом с proposal, tasks и design пережил бы задачу и разошёлся бы с ней молча. Ревью дизайна тоже растёт меткой: small — specs, medium — плюс rubric, large — плюс architecture и вопрос автору о трёх формах решения. Раньше rubric и architecture включались одним условием, и medium получал ровно один проход, то есть не отличался от quick ничем. Разведены они потому, что зарабатывают на разном: рубрика порождает свойства узла и окупается уже на среднем изменении, её выход уезжает приёмочными критериями в tasks.md; архитектура отвечает на вопрос про второй способ, а он на среднем знакомом изменении отвечается «нет» ещё до запуска. small подешевел тремя способами сразу. Составом: приёмник тем не запускается, три темы ядра переходят к code сверкой по записанным инвариантам CLAUDE.md с потолком в одну находку, и это не «глубина ниже», а другой дом темы. Входом: specs читает только дельта-спеку, code — только индекс конвенций. Потолком: он появился у каждого опиниативного прохода, а не у одного basics, и у половин code он раздельный, потому что конвенционных находок больше по построению и в общем списке они вытеснили бы техническую половину. Сработавший потолок обязан быть объявлен строкой — молчащий срез неотличим от «больше не нашлось». Отрицательный тест small от этого стал жёстче, а не мягче: вопросы про обратимость миграции задавал приёмник тем, и на этой метке их не задаст никто. Пайплайн задачи вырос до двенадцати шагов. Тривиальность перестала решать состав ревью — она влияет только на explore; глубину обеих стадий называет метка. Проверено прогоном ревьюверов по готовому результату: девять расхождений найдено и починено — контракт находок печатал старый перечень проходов вместо плана по темам, три ссылки в task-batch указывали на шаг коммита вместо закрытия, запись changelog не переводила вопросы, адресованные passport и database, ops и adversary утверждали, что на нижних метках их вопросы задаёт basics, шаблон покрытия в review-code зашивал потолки small намертво, триггеры метки рассыпались на два списка против трёх, тема из директивы CLAUDE.md могла остаться без запуска исполнителя. Гейт зелёный: фронтматтеры, копии, одиннадцать диаграмм, ruff, pyrefly; docs.py прогнан на живом фикстуре и печатает категорию в отказе. Канон повышен до версии 6 с записью, выполнимой upgrade. Решения — 40–44. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Канон документов проекта
|
||||
|
||||
**Версия 5.**
|
||||
**Версия 6.**
|
||||
|
||||
Это **единственный дом определения канона**. Скиллы `init`, `canon` и `docs`
|
||||
читают его, а не пересказывают: три описания одной раскладки разъедутся, и
|
||||
@@ -47,10 +47,10 @@
|
||||
|
||||
## Раскладка
|
||||
|
||||
**Документ канона — это тема ревью, а тема живёт файлом или каталогом.**
|
||||
`docs/security.md` и `docs/security/` — одно и то же; форму выбирает проект по
|
||||
объёму написанного, и переход между формами не меняет ни канон, ни версию. Обе
|
||||
формы сразу — ошибка: два дома для одного факта расходятся молча.
|
||||
**Документ канона живёт файлом или каталогом.** `docs/security.md` и
|
||||
`docs/security/` — одно и то же; форму выбирает проект по объёму написанного, и
|
||||
переход между формами не меняет ни канон, ни версию. Обе формы сразу — ошибка:
|
||||
два дома для одного факта расходятся молча.
|
||||
|
||||
```
|
||||
CLAUDE.md памятка агенту: что это, стек, инварианты с
|
||||
@@ -75,21 +75,76 @@ openspec/
|
||||
changes/archive/ архив изменений с design.md — сырьё для ADR
|
||||
```
|
||||
|
||||
**У темы-каталога обязателен `README.md`** — вход, по которому её читают агенты.
|
||||
**У документа-каталога обязателен `README.md`** — вход, по которому его читают агенты.
|
||||
`adr/` в форме каталога держит ещё и `template.md`, а записи именуются
|
||||
`ADR-ГГГГ-ММ-ДД-slug.md`.
|
||||
|
||||
**Список тем открытый, и это не послабление, а механизм.** Всё, что проект
|
||||
кладёт в `docs/`, становится темой ревью: у конвейера есть приёмник для темы, к
|
||||
которой нет именной оптики, и заведён он ровно за этим. Завёл
|
||||
`docs/accessibility.md` — появилась тема `accessibility`, и она попадает в план
|
||||
каждого прогона. Не темы ровно две: `docs/tasks/` (его ведёт скилл `tasks`)
|
||||
и `docs/review.*` — это настройка самого конвейера, слой над темами.
|
||||
## Три категории документов
|
||||
|
||||
Раньше здесь стояло плоское правило «каждый документ `docs/` — тема ревью». Оно
|
||||
неверно ровно наполовину: паспорт и схема хранилища ревью нужны, но темами не
|
||||
являются, а журнал решений и журнал наблюдений ревью изменения не нужны вовсе.
|
||||
Плоское правило заставляло разметчика либо плодить фантомные темы, либо терять
|
||||
документы молча — а молчащая потеря и есть то, против чего канон написан.
|
||||
|
||||
**Разрез один и проверяемый: можно ли по документу сказать «в этом изменении
|
||||
сделано не так»?**
|
||||
|
||||
| Категория | Ответ на разрез | Что с ней делает ревью |
|
||||
| --- | --- | --- |
|
||||
| **тема** | да, прямо | заводит направление проверки и требует исполнителя |
|
||||
| **источник темы** | нет, но он задаёт границу, по которой судит чужая тема | читается как материал, своей темы не порождает |
|
||||
| **процессный документ** | нет: он про то, как мы работаем, а не про изменение | не судит по нему изменение |
|
||||
|
||||
| Документ | Категория | Куда питает |
|
||||
| --- | --- | --- |
|
||||
| `conventions.*` | тема | `conventions` |
|
||||
| `security.*` | тема | `security` |
|
||||
| `architecture.*` | тема | `architecture`; раздел эксплуатации — `operations` |
|
||||
| *свой документ проекта* | тема | своя тема, именем документа |
|
||||
| `passport.*` | источник | `architecture` — граница домена, «чем **не** является» |
|
||||
| `database.*` | источник | `operations` — схема и настройки с числами |
|
||||
| `CLAUDE.md`, `AGENTS.md` | источник | `autotests` (семантика гейта); инварианты — сквозные |
|
||||
| `openspec/specs/` | источник | `requirements` |
|
||||
| `tasks/` | процессный | — |
|
||||
| `review.*` | процессный | — (настройка самого конвейера, слой **над** темами) |
|
||||
| `adr.*` | процессный | — |
|
||||
| `research.*` | процессный | — |
|
||||
| `.pm.json` | процессный | — (служебный файл, не документ) |
|
||||
|
||||
**Список тем открытый, и это не послабление, а механизм.** Категории
|
||||
`источник` и `процессный` **закрыты** — они перечислены здесь поимённо и
|
||||
проектом не пополняются. Всё остальное, что проект кладёт в `docs/`, — тема: у
|
||||
конвейера есть приёмник для темы, к которой нет именной оптики, и заведён он
|
||||
ровно за этим. Завёл `docs/accessibility.md` — появилась тема `accessibility`, и
|
||||
она попадает в план каждого прогона.
|
||||
|
||||
Отсюда следствие, ради которого правило и заведено: **`docs/` — это конфигурация
|
||||
ревью.** Проект настраивает проверку тем, что пишет о себе, а не отдельным файлом
|
||||
настроек, который разошёлся бы с документами.
|
||||
|
||||
**«Не судит по нему» и «не открывает» — не одно и то же, и разница существенна.**
|
||||
`docs/review.*` проходы читают на каждом прогоне: там лежат вопросы по темам,
|
||||
журнал дефектов, типовые узлы и типовые ложноположительные. Это чтение конвейером
|
||||
**собственной настройки**, а не суждение об изменении, и потому оно законно.
|
||||
`adr/`, `research/` и `tasks/` не открывает никто: по ним изменение не судят, и
|
||||
настройкой конвейера они не являются.
|
||||
|
||||
**Процессный документ — не документ второго сорта.** `adr/` и `research/`
|
||||
проверяются наравне с остальными, но **сверкой документации**, а не прогоном
|
||||
ревью: ADR без ссылки на архивный `design.md`, замена без парного статуса, число
|
||||
без провенанса — это работа агентов `doc-consistency` и `doc-code-drift`, и она
|
||||
осталась там же, где была. Изменилось одно: прогон ревью не открывает их как
|
||||
критерий и не судит по ним изменение.
|
||||
|
||||
Цена этого решения записана, а не подразумевается: **расхождение изменения с
|
||||
записанным решением прогоном больше не ловится.** Раньше архитектурный проход
|
||||
читал `adr/` и мог сказать «здесь отменено решение ADR-2026-03-11, а парного
|
||||
статуса нет»; теперь это скажет только `doc-consistency` на сессии между
|
||||
спринтами. Сделка сознательная — ADR объясняет прошлое, а не предъявляет
|
||||
требование к изменению, и чтение всего каталога решений на каждой задаче
|
||||
оплачивалось на каждой, а срабатывало на единицах.
|
||||
|
||||
### Имена файлов английские, текст русский
|
||||
|
||||
**Текст документов русский; имена файлов, capability и задач — английские,
|
||||
@@ -116,30 +171,35 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
## Роли документов и темы ревью
|
||||
|
||||
Одна строка на каждый — на какой вопрос он отвечает и какую тему ревью питает.
|
||||
**Кто именно закрывает тему, здесь не указано намеренно**: это зависит от ступени
|
||||
прогона и меняется вместе с конвейером, а документ живёт дольше. Раскладку
|
||||
«тема → проход → глубина» держит скилл `av-dev-pipeline:review-pipeline`.
|
||||
Одна строка на каждый — на какой вопрос он отвечает, в какой он категории и
|
||||
какую тему питает. **Кто именно закрывает тему, здесь не указано намеренно**: это
|
||||
зависит от метки прогона и меняется вместе с конвейером, а документ живёт
|
||||
дольше. Раскладку «тема → проход → глубина» держит скилл
|
||||
`av-dev-pipeline:review-pipeline`.
|
||||
|
||||
**Общего словаря у канона с конвейером ровно два вида имён: имена тем и имена
|
||||
ступеней.** Ими проект и настраивает ревью — вопросами по темам и триггерами
|
||||
профиля. **Имён проходов канон не называет нигде**, включая вывод `docs.py`:
|
||||
проход переименовывается и переезжает между ступенями, и канон, назвавший его, в
|
||||
**Общего словаря у канона с конвейером ровно три вида имён: имена категорий,
|
||||
имена тем и имена меток.** Категорий три — `тема`, `источник`, `процессный`;
|
||||
**меток тоже три, и они закрыты: `small`, `medium`, `large`.** Метка это итог
|
||||
классификации задачи, и по ней конвейер выбирает исполнителей на обеих стадиях
|
||||
ревью; проект её не выдумывает, а только уточняет триггеры. Ими проект и
|
||||
настраивает ревью — вопросами по темам и триггерами метки. **Имён проходов канон не называет нигде**, включая вывод `docs.py`:
|
||||
проход переименовывается и переезжает между метками, и канон, назвавший его, в
|
||||
этот день соврёт молча. Обратное направление законно — конвейер называет
|
||||
документы канона поимённо, потому что он их читатель.
|
||||
|
||||
| Документ | Вопрос | Тема ревью |
|
||||
| Документ | Вопрос | Категория и тема |
|
||||
| --- | --- | --- |
|
||||
| `CLAUDE.md`, `AGENTS.md` | что нельзя нарушать, чем краснеет гейт | `autotests`; инварианты — сквозные, во все темы |
|
||||
| `passport.*` | зачем и для кого, чем это **не** является | `architecture` |
|
||||
| `architecture.*` | как сложено и где что работает | `architecture`; раздел эксплуатации — `operations` |
|
||||
| `database.*` | что лежит в хранилище и какими настройками | `operations` |
|
||||
| `security.*` | против кого защищаемся и что вне модели | `security` |
|
||||
| `conventions.*` | как мы пишем код | `conventions` |
|
||||
| `research/` | что показала реальность, а не документация | `operations`, `requirements` |
|
||||
| `adr.*` | почему решено именно так | `architecture` |
|
||||
| `openspec/specs/` | что система делает — нормативно | `requirements` |
|
||||
| `review.*` | как настроен конвейер и что уже проскакивало | **не тема**: слой над всеми |
|
||||
| `CLAUDE.md`, `AGENTS.md` | что нельзя нарушать, чем краснеет гейт | источник: `autotests`; инварианты — сквозные, во все темы |
|
||||
| `passport.*` | зачем и для кого, чем это **не** является | источник: `architecture` |
|
||||
| `architecture.*` | как сложено и где что работает | тема `architecture`; раздел эксплуатации — `operations` |
|
||||
| `database.*` | что лежит в хранилище и какими настройками | источник: `operations` |
|
||||
| `security.*` | против кого защищаемся и что вне модели | тема `security` |
|
||||
| `conventions.*` | как мы пишем код | тема `conventions` |
|
||||
| `openspec/specs/` | что система делает — нормативно | источник: `requirements` |
|
||||
| `research.*` | что показала реальность, а не документация | процессный |
|
||||
| `adr.*` | почему решено именно так | процессный |
|
||||
| `review.*` | как настроен конвейер и что уже проскакивало | процессный: слой **над** темами |
|
||||
| `tasks/` | что делаем и в каком порядке | процессный |
|
||||
| *свой документ проекта* | что проект счёл нужным проверять | **своя тема**, именем документа |
|
||||
|
||||
### `passport.md`
|
||||
@@ -256,16 +316,22 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
- **Типовые ложноположительные** — находки, которые здесь выглядят убедительно и
|
||||
всегда неверны, каждая со строкой «почему здесь это не дефект»;
|
||||
- **Вопросы по темам** — в форме `<тема>: <вопрос> (<провенанс>)`. **Не по именам
|
||||
проходов**: проход уезжает между ступенями, а тема остаётся, и вопрос,
|
||||
проходов**: проход уезжает между метками, а тема остаётся, и вопрос,
|
||||
адресованный проходу, перестал бы задаваться молча в тот день, когда тот уехал
|
||||
в верхнюю ступень. Задаёт вопрос тот, кто закрывает тему на этом прогоне;
|
||||
- **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью:
|
||||
что в этом проекте считается **крупным или незнакомым** изменением (поднимает
|
||||
прогон до `wide`, верхней ступени, — и она рассчитана на 5–10% задач) и что
|
||||
считается **мелким** (опускает до `quick`). Перечнем мест, узлами или
|
||||
capability, а не вторым определением класса. Уточняет умолчания, а не отменяет
|
||||
их. Рабочее умолчание — `standard`: миграция схемы и публичный контракт ступень
|
||||
**не** поднимают, их проверяют проходы, которые в `standard` и так есть;
|
||||
в старшую метку. Задаёт вопрос тот, кто закрывает тему на этом прогоне.
|
||||
Адресовать можно только теме: `passport`, `database`, `adr`, `research` и
|
||||
`review` — не темы, и вопрос, адресованный им, не задаст никто;
|
||||
- **Триггеры метки** — проектная конкретизация правила выбора метки ревью,
|
||||
**тремя списками**. Два поднимают, по одному на ось: что в этом проекте считается
|
||||
**крупным** (объём: сколько узлов и слоёв трогает) и что считается
|
||||
**незнакомым** (форма решения: известна до начала или нащупывается по ходу).
|
||||
Любая из двух осей поднимает прогон до `large`, старшей метки, — а она
|
||||
рассчитана на 5–10% задач. Третий список — что считается **мелким** (опускает
|
||||
до `small`); он один, потому что вниз метку опускает только совпадение обеих
|
||||
осей сразу. Перечнем мест, узлами или capability, а не вторым определением
|
||||
класса. Уточняет умолчания, а не отменяет их. Рабочее умолчание — `medium`:
|
||||
миграция схемы и публичный контракт метку **не** поднимают, их проверяют
|
||||
проходы, которые в `medium` и так есть;
|
||||
- **Недоступно проверке** — два подраздела, оба **по темам**: «не проверит ни
|
||||
один проход» (принципиальная граница, по факту промаха не пересматривается) и
|
||||
«перестали проверять сознательно» (пересматривается первым). Тема, у которой в
|
||||
@@ -441,7 +507,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
```json
|
||||
{
|
||||
"canon": 4,
|
||||
"canon": 6,
|
||||
"migrations": "internal/store/migrations",
|
||||
"tasks": {
|
||||
"backlog": "INDEX.md"
|
||||
|
||||
Reference in New Issue
Block a user