Files
dev-skills/av-dev-pipeline/skills/review-pipeline/references/project-facts.md
T
avandClaude Opus 5 21b840a8e4 профили ревью: тяжёлые проходы в верхнюю ступень, на умолчании — один базовый
Тема 33 сняла самую большую разовую статью расхода, но не тронула главную —
частоту. Меряющая пара стояла в standard, то есть на большинстве задач, и именно
она делала прогон долгим: два прохода держат машину, идут цепочкой и доказывают
находки запуском. Цель разбора названа прямо: лучше поправить в следующей задаче,
чем держать одну два часа.

adversary и ops переехали в wide. Стадия осталась самой урожайной за всю историю
замеров — пять из семи выживших находок дозапуска и единственная находка про
молчаливый старт отката, — но её ценность оплачивается на каждой задаче, а
получается на немногих. Решение по цене, не по ценности.

Заведён review-basics: мелкая осадка двух тяжёлых проходов, без единого запуска.
Стоит только в standard. Восемь вопросов, на которые отвечают чтением: таймаут и
отказ соседа, идемпотентность и одновременная запись, остановка на середине,
частичный откат при двух версиях, наблюдаемость и тишина, очевидный рост объёма,
второй способ мимо единой точки (грепом, не картой), что отсюда удалить. Потолок
4 находки, машину не держит, ничего не меряет.

Вопрос про частичный откат — не для полноты списка. Без него правило «миграция
схемы не поднимает ступень» рассыпалось бы: раньше миграцию разбирал ops, а он
теперь наверху. Проход заведён затем, чтобы у standard остался хоть один взгляд
на ось времени.

Модель у него верхняя, opus, и это не спорит со словом «средний»: усилие режется
входом и потолком, а не моделью. Дешёвая модель на опиниативном проходе платит
триажем — это записанный замер, отменять его без нового замера нечем.

Лестница вышла 4/5/7. Главный выигрыш не в числе проходов, а в том, что из
standard ушла цепочка: теперь там гейт, три прохода одним сообщением и триаж —
граф плоский, ждать некому.

Правило выбора ступени переписано на два вопроса, и объём изменения вошёл в него
впервые. Крупное или незнакомое — трогает несколько узлов, переносит
ответственность, форму решения нащупывают по ходу — это wide, и он рассчитан на
5-10% задач. Мелкое — один узел, форма очевидна заранее, откат сводится к
обратной правке — quick. Всё остальное standard, рабочее умолчание. Раньше
ступень выбиралась только по классу изменения и на размер смотреть запрещала;
теперь признаков два: класс отвечает за обратимость, объём — за цену
разбирательства.

Отрицательный тест сохранил прежнюю мудрость в новой рамке: что после мерджа не
откатывается обратной правкой — не quick, каким бы маленьким ни был дифф. Три
строки миграции идут в standard.

Спорный случай решается вниз, и асимметрия объяснена ценой: ошибка в сторону
standard стоит находки на следующей задаче, ошибка в обратную — трёх тяжёлых
проходов на каждой задаче, выбранной неверно.

Сделка записана вместе с обратной связью, иначе это тихая потеря качества. На
quick и standard не проверяется ничего, что требует запуска: построенный путь,
эксперимент против драйвера, любое число. Это самая крупная граница покрытия
конвейера, и она идёт строкой в каждом таком прогоне поимённо. Сигналов о том,
что ступень занижена, два: журнал дефектов в docs/review.md и сам basics —
он единственный, кто смотрит на дифф целиком на нижних ступенях, и обязан
сказать строкой, если задача выглядит крупнее профиля.

Побочно: условие профиля design то же самое, так что rubric и architecture на
предложении тоже упали до 5-10% задач.

Тема 34 в DECISIONS.md, следствия 130-133. Версия канона не поднята; инструкция
проекту дописана в пункт 8 записи «Версия 4».

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 19:29:07 +03:00

100 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Откуда проход берёт проектную конкретику
Конвейер общий, находки — проектные. Проход, не знающий, что в этом проекте
нельзя нарушать, чем краснеет гейт и сколько данных реально идёт через узел,
выдаёт правдоподобные общие места: их дорого опровергать и нечем подтверждать.
Отдельного файла-брифа **нет**. Проектная конкретика живёт в документах канона
`av-dev-pm`, и проход читает их напрямую: пути жёсткие, посредник не нужен, а
второй дом для тех же фактов разошёлся бы и выглядел актуальным.
Определение канона — в плагине `av-dev-pm`,
`skills/canon/references/canon.md`. Здесь только карта «что нужно проходу →
где это лежит».
## Карта
| Что нужно проходу | Где лежит |
| --- | --- |
| что система делает и **чего не делает**, граница домена | `docs/passport.md` |
| инварианты **с severity рядом с формулировкой** | `CLAUDE.md`, раздел инвариантов |
| команда гейта, чем краснеет безусловно, чего в нём нет, кто гоняет дорогое | `CLAUDE.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/` |
## Сшивать обязаны проходы
Раньше эти факты лежали рядом в одном файле, и соседство работало само. Теперь
они разложены по домам, и **проход обязан собрать их сам** — иначе снимет верное
число и честно понизит находку до гипотезы, потому что сравнить будет не с чем.
Два обязательных стыка:
- **замер + настройка.** «Пик 768 МиБ» — аномалия только рядом со строкой
«запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась
5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом
занятости. Числа в `docs/research/`, настройки в `docs/database.md`, и оба
читает `ops` и `adversary`.
- **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там
нет — она **выводится по обратимости последствия** и помечается «выведена по
обратимости», а не выдаётся за решение проекта.
**У `basics` стыков нет, и это не упущение.** Он не меряет, поэтому сшивать число
с настройкой ему нечего; единственное его основание для `critical` — инвариант из
`CLAUDE.md`, всё остальное он формулирует условиями и оставляет гипотезой. Его
вход намеренно узкий: единые точки и внешние зависимости из `docs/architecture.md`,
инварианты из `CLAUDE.md`, журнал из `docs/review.md`. Широкий вход — это профиль
`wide`, и там он есть у `architecture`.
## Деградация — поразрядная
Документа нет — деградирует то, что из него читалось, и **только оно**. Каждый
проход пишет **свою** строку в границы покрытия; триаж собирает их в один
список и **не сливает в одну строку**: разные пробелы чинятся разным — периметр
пишется руками за десять минут, а числа требуют замера.
**Кто какой документ читает — не здесь.** Полный список читателей ведёт канон
(`Skill av-dev-pm:canon`, его `references/canon.md`, таблица «Кто читает»); ниже —
только **последствие** отсутствия, и оно называет самое дорогое, а не всех
пострадавших. Два списка читателей уже однажды разошлись; второго раза не надо.
| Нет документа | Что деградирует |
| --- | --- |
| `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.md` в
проекте нет» читается иначе, чем «есть, но периметр не назван». Без причины
строка неотличима от «мы просто не стали» и перестаёт читаться на третьей задаче.
**Документов канона нет вовсе** — проект не приведён к канону. Это не повод
работать вслепую: скажи об этом строкой и предложи `av-dev-pm:canon`. Одна
операция на проект против деградации на каждой задаче.
## Правило чтения
- **Читай в источнике, не по памяти.** Документы правятся по ходу работы, в том
числе этой же задачей.
- **Число без провенанса — условие, а не утверждение.** Число, чей источник по
ссылке не подтвердился, читается как условие и **называется расходящимся**, а
не подменяется догадкой.
- **Пустое, названное пустым, — это факт.** «Внешних зависимостей нет — смотри
на диск и на СУБД» экономит обязательный вопрос. Отсутствие строки — не факт,
а пробел, и его надо назвать в границах покрытия.
- **Свойство, ставшее правилом линтера, из конвенций удалено** и лежит в
перечне механизированного в `docs/conventions/README.md`. Проверять его
проходом — тратить внимание на уже проверенное.