Замечено при сверке документов канона с составом ступеней: три документа
остались без читателя ниже wide — security.md, database.md и adr/. Проект
поддерживал их, а на 90% задач не открывал никто. Причина оказалась не в
переезде проходов, а в том, как описан состав прогона.
Список тем нигде не был записан: он существовал побочным продуктом списка
проходов. Проход уезжал в верхнюю ступень — и тема уезжала с ним беззвучно.
Отчёт честно говорил «ops не запускался» и не говорил «эксплуатацию не смотрел
никто», а нужно второе. Теперь тема первична, проход вторичен — это правило 0
конвейера, а прогон описывается таблицей «тема → дом → глубина → кто закрывает»,
и таблица есть в каждом отчёте.
Тема есть документ, список открытый. Всё, что проект кладёт в docs/, становится
темой ревью; запретить нельзя, разрешения не надо. Не темы ровно две: docs/tasks/
и docs/review — настройка самого конвейера, слой над темами. Отсюда главное:
docs/ перестал быть документацией и стал конфигурацией конвейера. Проект
настраивает проверку тем, что пишет о себе, а не отдельным файлом настроек,
который разошёлся бы с документами. Ядро — requirements, autotests, conventions,
architecture, security, operations; всё сверх разбирает basics, потому что
именных проходов конечное число, а тем столько, сколько заведёт проект.
Тема живёт файлом или каталогом, на выбор проекта: docs/security.md и
docs/security/ — одно и то же. Прежде форма была задана поимённо и обосновать её
было нечем; заодно в TODO висел вопрос «а если architecture.md разрастётся».
Теперь ответ механический: разросся — стал каталогом с README.md, и это не смена
версии. Обе формы сразу — ошибка, docs.py её ловит.
Заведён review-scope, sonnet, стадия 0, до гейта: находит документы, выводит
темы, назначает глубины, выбирает ступень с обоснованием. Довод оказался сильнее
синхронизации документов — до сих пор профиль называл тот же оркестратор,
который написал код, то есть в точке выбора глубины проверки разведённости с
автором не было вовсе, а решала она под давлением «я почти закончил». Вызывающий
пайплайн профиль больше не передаёт. Поднять и понизить ступень разметчик вправе
одинаково, но обоснование обязательно всегда.
Sonnet ему хватает потому, что вывод устроен как список: каждый файл в docs/
обязан попасть в план темой или строкой «не тема, потому что», и план сверяется с
ls docs/ за секунду. Выбор ступени — суждение, но у него три независимых
корректора: отрицательный тест quick, правило «спорный случай вниз» и сигнал
basics о заниженной ступени.
Разметчик передаёт адреса, а не пересказ. Проект однажды уже держал
review-brief.md и убрал его: второй дом расходится с первым и выглядит
актуальным. Пересказ в задании — тот же посредник, живущий один прогон.
Исключение одно: отсутствие дома, этого проход сам дёшево не выяснит.
quick и standard совпали составом и разошлись глубиной — иначе требование
«нижние ступени закрывают все темы, просто не так глубоко» не выполняется.
Глубин три, и они про способ доказательства, а не про старательность: сверка
(открыть дом, открыть дифф, сравнить), разбор (построить сценарий рассуждением),
доказательство (прогнать, померить, построить путь). Третья есть только в wide.
Цена принята: это единственное место, где профиль не выводится из списка
проходов, поэтому глубина объявляется в отчёте наравне со ступенью.
review-code переписан, и это оказалось крупнее исходной находки: код как код не
читал никто. specs сверял с требованиями, basics — с отказами окружения,
architecture — с устройством, а code был проходом только по прозаическим
конвенциям и прямо объявлял, что рантайм и логика не его. «Здесь ошибка в логике»
не говорил вообще никто. Теперь у прохода две половины: девять классов
технического дефекта (необработанная ветка отказа, пустое и нулевое, граница
диапазона, перепутанный операнд, неосвобождённый ресурс, изменение под итерацией,
неверно применённый интерфейс библиотеки, недостижимая ветка, «сделано соседнее»)
и прежняя сверка с конвенциями. Модель поднята до opus по признаку темы 35: цена
пропущенной находки — дефект в проде.
Канон повышен до версии 5: форма дома на выбор, открытый список тем, AGENTS.md
законно лежит рядом с CLAUDE.md, «Вопросы к проходам» → «Вопросы по темам» (имя
прохода переезд не переживает, тема переживает), «Недоступно проверке» — тоже по
темам. docs.py переписан под темы: ловит двойной дом, принимает обе формы,
перечисляет свои темы проекта вместо «файл вне канона».
Побочно закрыт давний пункт TODO про каталожную форму architecture.md — решать
больше нечего.
Прогон от всего этого стал дороже, а не дешевле, впервые за сессию: плюс scope в
голове каждого прогона, плюс code на opus, плюс basics теперь и в quick. Куплены
разведённость выбора ступени, видимость непокрытых тем и технический разбор кода,
которого не было вовсе.
Тема 36 в DECISIONS.md, следствия 137-140.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
description:"Конвейер ревью изменения — детерминированный гейт, сверка с дельта-спеками в обе стороны, базовый проход на отказы и лишнее, а в верхнем профиле враждебные постановки, эксплуатационный постмортем и архитектурный проход; триаж обязателен всегда. Три ступени стоимости: quick (4 прохода), standard (5, рабочее умолчание), wide (7, только крупное или незнакомое — 5-10% задач). Ступень выбирается по объёму и незнакомости изменения, спорный случай решается вниз. Порядок прогона — граф зависимостей, а не очередь: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Линейный прогон — по слову оператора или на занятой машине. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода."
description:"Конвейер ревью изменения, устроенный по темам: каждый документ проекта — тема ревью, а проход лишь закрывает тему на заданной глубине. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список открытый, свои темы проект заводит документом. Прогон начинает разметчик: находит документы, выводит темы, выбирает ступень с обоснованием и раздаёт темы проходам. Три ступени: quick и standard закрывают все темы (сверкой и разбором), wide добавляет доказательство — враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе. Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода."
---
# Конвейер ревью
@@ -8,10 +8,19 @@ description: "Конвейер ревью изменения — детерми
| `standard` | **рабочее умолчание**: всё, что не мелкое и не крупное | 0, 1, 2, 3, 5 | 6 | большинство |
| `wide` | крупное или незнакомое: большой рефакторинг, функциональность, форму которой ещё предстоит нащупать | 0, 1, 2, 4, 5 | 8 | **5–10%** |
| `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 1–3 | — |
**`quick` и `standard` совпадают составом и различаются глубиной** — это
единственное место конвейера, где профиль не выводится из одного лишь списка
проходов. Поэтому глубина объявляется в отчёте наравне с профилем, а план
разметчика называет её по каждой теме. Проверять надо два факта вместо одного, и
оба напечатаны.
**Три глубины, и они не про старательность, а про способ доказательства.**
**Сверка** — открыть дом темы, открыть дифф, сравнить. **Разбор** — построить
сценарий рассуждением, ничего не запуская. **Доказательство** — прогнать,
померить, построить путь. Только третья требует машины, и только она стоит часов.
**`wide` назван по тому, что он добавляет: вход шире диффа.** Он единственный, где
живут тяжёлые проходы — враждебный, эксплуатационный и архитектурный, — и
единственный, где что-то **запускается и меряется**. Отсюда и его доля: три прохода
на стадии 3, два из них держат машину и потому идут цепочкой, а не разом. Это и
есть те самые долгие часы, и платить их каждой задаче не за что.
живут тяжёлые проходы, и единственный, где что-то **запускается**. `basics` в нём
берёт только проектные темы; своих тем у проекта нет — он не запускается вовсе, и
план говорит об этом строкой.
**Доля 5–10% — не пожелание, а проверка правила.**Она не считается механически, но
читается по журналу: если `wide` уходит каждая третья задача, ступень выбирают по
ощущению важности, а не по факту изменения. Обратный перекос виден иначе — по
журналу проскочивших дефектов в `docs/review.md`: класс, который ловят только
меряющие проходы, начинает всплывать после мерджа.
**Доля 5–10% — не пожелание, а проверка правила.**Если `wide` уходит каждая
третья задача, ступень выбирают по ощущению важности. Обратный перекос виден по
журналу проскочивших дефектов: класс, который ловят только меряющие проходы,
начинает всплывать после мерджа.
**Состав сверяется по этой таблице до коммита.** Реестр из трёх-семи проходов
проверяется взглядом — и это единственная защита от промаха, который уже
случился: пропуск прохода**не отличим от прохода без находок** (гейт зелёный,
спеки сошлись, отчёт выглядит полным), а заметить его мог бы только триаж,
который сам заполняется тем, что ему подали. Отчёт обязан перечислять запущенные
проходы **поимённо и с исходом**; непущенный идёт строкой «не запускался» в
границы покрытия, а не отсутствует. Цена молчащего пропуска измерена: семь
**Состав сверяется до коммита — по плану разметчика, а не по этой таблице.** План
и есть реестр: тема, дом, глубина, кто закрывает. Это единственная защита от
промаха, который уже случился: пропуск **не отличим от прохода без находок** (гейт
зелёный, спеки сошлись, отчёт выглядит полным), а заметить его мог бы только
триаж, который сам заполняется тем, что ему подали. Непущенное идёт строкой «не
запускался» с причиной, а не отсутствует. Цена молчащего пропуска измерена: семь
находок и отдельная задача на их дозакрытие.
Правило выбора — **два вопроса по факту изменения, не по ощущению важности**.
Отвечать по порядку, первый подошедший ответ и есть профиль:
Дом правила здесь, а применяет его `review-scope` на стадии 0 — не автор
изменения. Отвечать по порядку, первый подошедший ответ и есть профиль:
1.**Изменение крупное или незнакомое?** → `wide`. Крупное — трогает несколько
узлов или слоёв разом, переносит ответственность между ними, перекладывает
@@ -221,17 +296,17 @@ charter'а, а модель потом двигает калибровка, и
стоит находки, которая всплывёт на следующей задаче или в журнале дефектов.
Ошибка в обратную стоит трёх тяжёлых проходов, двое из которых держат машину и
идут цепочкой, — и платится она **на каждой** задаче, выбранной неверно.
- **Спорно между `quick` и `standard` → бери `standard`.** Здесь разница в один
дешёвый проход, зато он единственный, кто на этих ступенях вообще смотрит на
отказы и на эксплуатацию.
- **Спорно между `quick` и `standard` → бери `standard`.** Здесь состав тот же, и
разница только в глубине трёх тем: сверка против разбора. Дёшево, и потому
сомнение решается в пользу разбора.
**Выбор сделан в пользу пропускной способности, и это записано, а не подразумевается.**
Конвейер настроен на поток задач, а не на максимум находок с каждой: поправить в
следующей задаче дешевле, чем держать одну два часа. Отсюда три обязанности,
без которых сделка превращается в незаметную потерю качества:
- **границы покрытия называют непущенные проходы поимённо** — иначе `quick`
выглядит так же, как `wide` без находок;
- **границы покрытия называют темы и их глубину**, а не только запущенные
проходы — иначе `quick` выглядит так же, как `wide` без находок;
- **журнал дефектов в `docs/review.md` перестаёт быть хорошей практикой и
становится единственной обратной связью**: проскочивший дефект — единственный
сигнал, что ступень выбрана слишком низко;
@@ -246,46 +321,50 @@ charter'а, а модель потом двигает калибровка, и
часть, которая сама по себе была бы `quick`.
Обратное тоже верно и тоже не бесплатно: у каждой задачи есть **несокращаемый
костяк из четырёх проходов** (гейт, спеки, код, триаж). Разрезать задачу, обе
половины которой остаются в одном профиле, — значит заплатить костяк дважды за ту
же проверку. Резать стоит там, где разрез **снимает дорогой проход с большей
части диффа**. Шов и правило нарезки живут у того, кто ведёт задачи, — скилл
`av-dev-pm:tasks`, его `references/split.md`. Пути туда конвейер не выносит: за
пределы своего плагина он ходит вызовом скилла, а не файлом.
костяк из шести проходов** (разметка, гейт, спеки, код, темы, триаж). Разрезать
задачу, обе половины которой остаются в одном профиле, — значит заплатить костяк
дважды за ту же проверку. Резать стоит там, где разрез **снимает доказательство с
большей части диффа**. Шов и правило нарезки живут у того, кто ведёт задачи, —
скилл `av-dev-pm:tasks`, его `references/split.md`. Пути туда конвейер не
выносит: за пределы своего плагина он ходит вызовом скилла, а не файлом.
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно
попадает в границы покрытия строкой «профиль понижен до X, потому что …».
**Профиль и глубина объявляются в отчёте, и оба с обоснованием.** Ступень
выбирает `review-scope`; он вправе и поднять, и понизить её — но не молча: строка
«ступень X, потому что …» обязательна на каждом прогоне, а не только когда
ступень отличается от ожидаемой.
## Порядок прогона — граф, а не очередь
Профиль отвечает «какие проходы», порядок — «что кого ждёт». Стадии остаются
единицей **состава** (профиль набирается стадиями, см. таблицу выше), но порядок
задают **не их номера**: между стадиями 1–3 настоящих зависимостей нет — ни один
проход не читает вывод другого, — и очередь между ними была бы платой ни за что.
Профиль отвечает «какие темы и на какой глубине», порядок — «что кого ждёт».
Стадии остаются единицей **состава**, но порядок задают **не их номера**: между
стадиями 2–4 настоящих зависимостей нет — ни один проход не читает вывод другого,
— и очередь между ними была бы платой ни за что.
Рёбер два вида, и они разной природы. Путать их нельзя: первое про
**осмысленность** (на красном гейте опиниативный проход не о чем), второе про
**железо**.
**осмысленность** (без плана задание не определено, на красном гейте опиниативный
проход не о чем), второе про **железо**.
| Ребро | Смысл | Между кем |
|---|---|---|
| **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | гейт → все опиниативные; все проходы → триаж |
| **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | разметка → все; гейт → все опиниативные; все проходы → триаж |
| **конфликт за ресурс** | A и B не держат машину одновременно; кто из них первый — неважно, направления у ребра нет | проходы, помеченные «держит машину» |
```mermaid
flowchart TD
gate["gate<br/>(стадия 0, держит машину)"]
scope["scope — разметка<br/>(стадия 0, темы и ступень)"]
gate["gate<br/>(стадия 1, держит машину)"]
specs["specs"]
code["code"]
basics["basics<br/>(standard)"]
basics["basics<br/>(quick, standard: темы;<br/>wide: только свои темы проекта)"]
adversary["adversary<br/>(wide, держит машину)"]
ops["ops<br/>(wide, держит машину)"]
architecture["architecture<br/>(wide)"]
triage["triage — единственный сток"]
scope -->|план| gate
gate -->|зелёный| specs
gate -->|зелёный| code
gate -->|"зелёный, standard"| basics
gate -->|"зелёный, темы по плану"| basics
gate -->|"зелёный, wide"| adversary
gate -->|"зелёный, wide"| ops
gate -->|"зелёный, wide"| architecture
@@ -299,11 +378,11 @@ flowchart TD
```
Читается граф так: **всё, у чего входящие рёбра закрыты, уходит одним
сообщением**. В`quick` после зелёного гейта это `specs` и `code` разом, и сразу
триаж. В`standard` к ним третьим добавляется `basics` — все трое уходят одним
сообщением, ждать друг друга им нечего. В`wide` вместо `basics` идут три тяжёлых:
`architecture` и первый из меряющей пары — сразу, второй меряющий — следом за
первым, и он же определяет, когда стартует триаж.
сообщением**. Разметка идёт первой и одна — до неё неизвестно ни что проверять,
ни на какой ступени. В `quick` и `standard` после зелёного гейта уходят разом
`specs`, `code` и `basics`, и сразу триаж. В`wide` вместо тем`basics` идут три
тяжёлых: `architecture` и первый из меряющей пары — сразу, второй меряющий —
следом за первым, и он же определяет, когда стартует триаж.
**Схема здесь старше прозы.** Она не иллюстрация к тексту, а сам алгоритм
планировщика; проза ниже объясняет рёбра и называет их цену. Разошлись — прав
@@ -330,7 +409,7 @@ flowchart TD
| `adversary` | да | находка есть **построенный путь**: он пишет падающий тест и гоняет его |
| `ops` | да | доказывает числами: время удержания блокировки, пик кучи, темп роста журнала |
| `triage` | да | проверяет оракул `critical`/`major` запуском — но он сток и тоже один |
| `specs`, `code`, `basics`, `architecture`, `rubric` | нет | читают и рассуждают, ничего не исполняют |
| `scope`, `specs`, `code`, `basics`, `architecture`, `rubric` | нет | читают и рассуждают, ничего не исполняют |
**Правило про ресурс, а не про имена.** Раньше здесь стояло именованное
исключение «`adversary` и `ops`»; оно рассыпается, как только проход начнёт
@@ -387,10 +466,33 @@ flowchart TD
Режим объявляется в отчёте наравне с профилем: **`по графу`** — одним словом,
**`линейно`** — с причиной (какой именно из трёх).
## Стадия 0 — Gate (обязательна во всех профилях)
## Стадия 0 — Разметка (обязательна во всех профилях)
Агент `review-gate`. Запускает команду гейта из семантики гейта в `CLAUDE.md` и
интерпретирует вывод.
Агент `review-scope`. Идёт **первым, до гейта**, и один: до его плана неизвестно
ни что проверять, ни на какой ступени.
Возвращает **план прогона**: список тем с домами и глубинами, ступень с
обоснованием, перечень документов, не ставших темами, и строку про найденные
директивы (`CLAUDE.md`, `AGENTS.md`). План уезжает в отчёт целиком и служит
границами покрытия.
**Он не судит по существу** — ни одной находки об изменении. Его ошибка это
пропущенная тема или не та ступень, и обе видны: план сверяется с `ls docs/` за
секунду, а заниженную ступень ловит `basics` своим сигналом.
**Ступень выбирает он, а не автор изменения.** Раньше профиль называл тот же
оркестратор, который писал код: он же решал, насколько глубоко его проверять, — и
разведённости с автором в этой точке не было вовсе. Вызывающий пайплайн профиль
больше не передаёт; он передаёт change, базу диффа и режим.
Право у разметчика симметричное: **поднять и понизить ступень он может
одинаково**, но обоснование обязательно в обоих случаях и всегда — строкой, какой
признак сработал и по какому факту.
## Стадия 1 — Gate (обязательна во всех профилях)
Агент `review-gate`. Закрывает тему `autotests`. Запускает команду гейта из
семантики гейта в `CLAUDE.md` и интерпретирует вывод.
**Пока гейт красный — опиниативные проходы не запускаются.** Оркестратор чинит и
перезапускает гейт. Исключение одно: отказ, унаследованный от базовой ветки
@@ -408,69 +510,81 @@ flowchart TD
Шаги, которые красят гейт безусловно, перечислены в `CLAUDE.md` с причиной. Проходу
запрещено списывать такой отказ в мелочь.
## Стадия 1 — Conformance (обязательна во всех профилях)
## Стадия 2 — Сверка (обязательна во всех профилях)
Два applicative-прохода: оба применяют**записанный** критерий, оба дешёвые.
Машину не держат ни один, ребра между ними нет — уходят одним сообщением сразу
после зелёного гейта, вместе со стадией 2 или 3 — той, что в профиле.
Два прохода, оба против**записанного** критерия. Машину не держат ни один, ребра
между ними нет — уходят одним сообщением сразу после зелёного гейта, вместе со
стадией 3 или 4 — той, что в профиле.
-`review-specs`— критерий взят из **дельта-спек предлагаемого изменения**, а не
из proposal, сообщения коммита или описания задачи. Сверка двунаправленная;
направление `code → spec` важнее.
-`review-code`— критерий взят из конвенций проекта, каталог
`docs/conventions/`. Берётся только та их часть, которая **не выражается
правилом**: механизируемое уже проверила стадия 0. Что именно механизировано,
перечисляет `conventions/README.md` — повторять это проходом вредно.
-`review-specs`закрывает тему `requirements`. Критерий взят из **дельта-спек
предлагаемого изменения**, а не из proposal, сообщения коммита или описания
задачи. Сверка двунаправленная; направление `code → spec` важнее.
-`review-code`закрывает тему `conventions` **и делает технический разбор
кода** — это две его половины. Первая ищет дефект, который сработает сам, на
обычном входе: необработанная ветка отказа, пустое значение, граница диапазона,
второй дом для тех же фактов разошёлся бы и выглядел актуальным.
Определение канона — в плагине `av-dev-pm`,
`skills/canon/references/canon.md`. Здесь только карта «что нужно проходу →
где это лежит».
`skills/canon/references/canon.md`. Здесь только карта «тема → её дом → что
оттуда берётся».
## Карта
## Карта тем
**Дом бывает файлом или каталогом** — `docs/security.md` и `docs/security/`
называют одну и ту же тему. Форму дома называет план разметчика; проход её не
угадывает.
| Тема | Дом | Что оттуда берётся |
| --- | --- | --- |
| `requirements` | `openspec/specs/`, `openspec/changes/<id>/specs/` | нормативное поведение и дельты изменения |
| `autotests` | `CLAUDE.md`, семантика гейта | команда гейта, чем краснеет безусловно, чего в нём нет, кто гоняет дорогое |
| `conventions` | `docs/conventions.*` | конвенции прозой и **что уже механизировано** правилом |
| `architecture` | `docs/architecture.*` | компоненты и capability, единые точки проекта |
| | `docs/passport.*` | что система делает и **чего не делает**, граница домена |
| | `docs/adr/` | почему решено так, отвергнутые варианты |
| `security` | `docs/security.*` | периметр, недоверенный вход, из чего строятся пути и ключи, что вне модели |
| `operations` | `docs/architecture.*`, раздел эксплуатации | окружение, внешние зависимости поимённо, наблюдатель, характер потока |
| | `docs/database.*` | чем физически лежит запись, что при чтении и записи, настройки с числовым значением |
| | `docs/research/` | измеренные числа **с провенансом**, поведение внешних систем на самом деле |
| *тема проекта* | её документ в `docs/` | то, что проект счёл нужным записать |
Сквозное, не привязанное к теме:
| Что нужно проходу | Где лежит |
| --- | --- |
| что система делает и **чего не делает**, граница домена | `docs/passport.md` |
| инварианты **с severity рядом с формулировкой** | `CLAUDE.md`, раздел инвариантов |
| команда гейта, чем краснеет безусловно, чего в нём нет, кто гоняет дорогое | `CLAUDE.md`, семантика гейта |
| инварианты **с severity рядом с формулировкой** | `CLAUDE.md` (и `AGENTS.md`, если он рядом), раздел инвариантов |
| что запускать запрещено, с путями; `testdata`; куда писать временное; имя основной ветки | `CLAUDE.md` |
| компоненты и capability, окружение, внешние зависимости поимённо, наблюдатель, характер потока, единые точки проекта | `docs/architecture.md` |
| чем физически лежит запись, что при чтении и записи, настройки с числовым значением | `docs/database.md` |
| периметр, недоверенный вход, из чего строятся пути и ключи, что вне модели | `docs/security.md` |
| измеренные числа **с провенансом**, поведение внешних систем на самом деле | `docs/research/` |
| конвенции прозой и **что уже механизировано** правилом | `docs/conventions/` |
| почему решено так, отвергнутые варианты | `docs/adr/` |
| типовые узлы, типовые ложноположительные, вопросы к проходам, **триггеры профиля**, недоступно проверке | `docs/review.md`, раздел настройки |
| прецеденты: воспроизведённые дефекты с оракулом | `docs/review.md`, журнал |
| нормативное поведение и дельты изменения | `openspec/specs/`, `openspec/changes/<id>/specs/` |
| типовые узлы, типовые ложноположительные, **вопросы по темам**, триггеры профиля, недоступно проверке | `docs/review.*`, раздел настройки |
| прецеденты: воспроизведённые дефекты с оракулом | `docs/review.*`, журнал |
**Вопросы проекта привязаны к теме, а не к имени прохода.** Раньше блок в
`docs/review.md` адресовался поимённо (`ops: <вопрос>`), и когда проход уехал в
верхнюю ступень, вопрос перестал задаваться молча. Тема переезд прохода
переживает.
## Сшивать обязаны проходы
@@ -50,9 +66,13 @@
**У `basics` стыков нет, и это не упущение.** Он не меряет, поэтому сшивать число
с настройкой ему нечего; единственное его основание для `critical` — инвариант из
`CLAUDE.md`, всё остальное он формулирует условиями и оставляет гипотезой. Его
вход намеренно узкий: единые точки и внешние зависимости из `docs/architecture.md`,
инварианты из `CLAUDE.md`, журнал из `docs/review.md`. Широкий вход — это профиль
`wide`, и там он есть у`architecture`.
вход намеренно узкий: дома тем из плана плюс инварианты и журнал. Широкий вход —
это профиль `wide`, и там он есть у`architecture`.
**У `scope` стыков нет по другой причине: он не читает содержимого.** Его дело —
найти дома и раздать темы, а не пересказать написанное. Пересказ сделал бы его
посредником между документом и проходом, а посредник расходится с источником и при
этом выглядит актуальным.
## Деградация — поразрядная
@@ -66,15 +86,17 @@
только **последствие** отсутствия, и оно называет самое дорогое, а не всех
пострадавших. Два списка читателей уже однажды разошлись; второго раза не надо.
| Нет документа | Что деградирует |
| Нет дома | Что деградирует |
| --- | --- |
| `CLAUDE.md` без инвариантов | `critical` по основанию «нарушен инвариант проекта» не присваивается никем |
| `docs/security.md` | `adversary` не знает периметра — формулирует условиями, `critical` не ставит |
| `docs/research/` | числа неизвестны `specs`, `ops`,`adversary` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» |
| `docs/database.md` | замер не с чем сравнить: находка не поднимается выше гипотезы |
| `docs/passport.md` | `architecture` теряет границу домена и вырождается в общее мнение |
| `docs/review.md` | `triage` отсеивает вслепую: типовых ложноположительных нет |
| `docs/architecture.md` | «не появился ли второй способ» не проверяется — единых точек не знает никто; `basics` теряет ещё и перечень внешних зависимостей |
| `docs/security.*` | тема `security` остаётся без дома: вопросы задаются по коду, `critical` не ставится, периметр неизвестен |
| `docs/research/` | числа неизвестны темам `operations` и`requirements` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» |
| `docs/database.*` | замер не с чем сравнить: находка темы `operations` не поднимается выше гипотезы |
| `docs/passport.*` | тема`architecture` теряет границу домена и вырождается в общее мнение |
| `docs/adr/` | «не отменяет ли изменение записанное решение» не спрашивает никто |
| `docs/review.*` | `triage` отсеивает вслепую: типовых ложноположительных нет; вопросы проекта по темам не задаются |
| `docs/conventions.*` | вторая половина `code` идёт вхолостую: записанных конвенций нет |
| `docs/architecture.*` | «не появился ли второй способ» не проверяется — единых точек не знает никто; тема `operations` теряет перечень внешних зависимостей |
Строка в границах покрытия обязана называть **причину**: «`docs/security.md` в
проекте нет» читается иначе, чем «есть, но периметр не назван». Без причины
Задачи из него заводит тот, кто ведёт задачи проекта;
- **одна строка границ покрытия**: какой профиль и режим гонялись, какие проходы
- **одна строка границ покрытия**: какая ступень и режим гонялись, какие проходы
не запускались и что проверить было невозможно. Доклад без неё сообщает
«проверено», не сообщая, что именно.
@@ -402,7 +408,7 @@ flowchart TD
спрашивай, запиши вопросом и доведи остаток.
- Держи вызывающего в цикле короткими репликами на переходах фаз, но не проси
подтверждать механику.
- **Занизить профиль ревью или пропустить проход — самый дешёвый способ
«ускориться», и он же самый дорогой по последствиям.** Защита одна: профиль
выбирается по факту изменения, состав сверяется поимённо, а непущенное
называется в отчёте строкой.
- **Занизить ступень ревью или пропустить тему — самый дешёвый способ
«ускориться», и он же самый дорогой по последствиям.** Защита устроена так,
что регулятора у тебя нет: ступень выбирает разметчик, план сверяется по темам,
непокрытое называется в отчёте строкой.
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.