From ea84a4fbb3287ad3708e57c62a8d785579eeae5b Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 6 Aug 2026 19:02:15 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B8=D0=BC=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E:=20=D1=81=D0=BD?= =?UTF-8?q?=D1=8F=D1=82=20=D0=BF=D1=80=D0=BE=D1=85=D0=BE=D0=B4=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D0=B9=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=B0=D0=BC=D0=B0=D1=8F=20=D0=B4=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B3=D0=B0=D1=8F=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Прогоны стали долгими, а счёт в токенах заметным. Разбор шёл не по находкам, а по статьям расхода. Две названы прямо: убрать reimpl и убрать fable. reimpl писал свою реализацию узла, не открывая существующую, и диффил по решениям. Его счёт определялся объёмом вывода — он один писал код, а не читал его, — и на прогоне это была самая большая строка. Снят по цене. Профиль deep от этого не похудел, а исчез: reimpl был единственным, чем он отличался от wide, и без него у двух имён оказался бы один состав. Ровно от этой болезни лечилась ступень wide решением JJJ — у профиля обязан быть один правильный ответ, иначе реестр состава нечем проверять. Ступеней три: quick, standard, wide. Вместе с профилем снято всё, что обслуживало только его. Барьер стоимости — он держал дорогой проход, чтобы тот не писал реализацию против кода, который через час перепишут; дорогого прохода нет, граф стал плоским во всех профилях, рёбер осталось два вида вместо трёх. Тест «идентичность, слияние, разбор» — полторы страницы, служившие единственной цели: выбрать deep не по ощущению; вместе с ним ушёл проектный перечень мест в docs/review.md и его скелет в каноне. Стадии перенумерованы: 0 гейт, 1 сверка, 2 враждебный и эксплуатационный, 3 архитектурный, 4 триаж — дыра на месте третьей читалась бы как пропущенная стадия. Снятие записано как сознательное сужение, а не как «класс оказался пустым». calibration.md требует замера на двух проектах перед удалением прохода; замера не было, было решение о цене. Поэтому в «Честном пределе» стоит строка: «не знаю, чего не знаю» больше не достаёт никто. Остаток независимого взгляда дают профиль design и architecture, но альтернативной реализации, с которой можно сдиффить решения, у конвейера нет. Класс уходит в границы покрытия каждого прогона, у проекта — в подраздел «перестали проверять сознательно». Без этой записи снятие через месяц читается как «проверено и признано лишним». fable снят с троих: review-triage, review-architecture, doc-code-drift — все на opus. Основание верхней модели «ошибка распространяется дальше самой находки» осталось, но оно объясняет, почему двое не опускаются до sonnet, а не почему им нужна ступень выше opus: разницы в пользу более дорогой модели не показал ни один прогон, а время и счёт она множила. Палитра схлопнулась до двух цветов, красного в репозитории больше нет, frontmatter.py теперь отвергнет модель вне sonnet и opus. Версия канона не поднята сознательно. Проектам всё равно надо снести перечень мест для deep из docs/review.md, поэтому пункт вписан в «Что сделать проекту» записи «Версия 4» — её ещё не гонял ни один проект, оба ждут в TODO. Тема 33 в DECISIONS.md, следствия 127-129. Co-Authored-By: Claude Opus 5 (1M context) --- DECISIONS.md | 70 +++++ README.md | 5 +- TODO.md | 4 + av-dev-pipeline/agents/review-architecture.md | 4 +- av-dev-pipeline/agents/review-code.md | 2 +- av-dev-pipeline/agents/review-reimpl.md | 164 ----------- av-dev-pipeline/agents/review-triage.md | 4 +- .../skills/review-pipeline/SKILL.md | 259 ++++++------------ .../review-pipeline/references/calibration.md | 1 - .../references/finding-contract.md | 4 +- .../references/project-facts.md | 4 +- av-dev-pipeline/skills/task-batch/SKILL.md | 6 +- av-dev-pipeline/skills/task-pipeline/SKILL.md | 3 +- av-dev-pm/agents/doc-code-drift.md | 4 +- av-dev-pm/skills/canon/references/canon.md | 17 +- .../skills/canon/references/changelog.md | 21 +- .../skills/canon/references/skeletons.md | 12 +- scripts/frontmatter.py | 2 +- 18 files changed, 193 insertions(+), 393 deletions(-) delete mode 100644 av-dev-pipeline/agents/review-reimpl.md diff --git a/DECISIONS.md b/DECISIONS.md index 50abb80..1088f49 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -2258,3 +2258,73 @@ dev-skills — **маркетплейс плагинов**: скилл комм 126. **Снятое слово называется вместе с заменой и остаётся записанным.** Убрать из текстов недостаточно: без записи «это снято и вот чем заменено» слово возвращается первым же, кто найдёт его удачным. + +## 33. Стоимость ревью: снят самый дорогой проход и самая дорогая модель (2026-08-06) + +Прогоны стали долгими, а счёт в токенах — заметным. Разбор шёл не по находкам, а +по статьям расхода: что в конвейере стоит больше всего и что из этого окупается. +Две статьи названы прямо оператором. + +**ААББОО. Проход независимой реализации снят целиком, и с ним профиль `deep`.** +`reimpl` писал свою реализацию узла, не открывая существующую, и диффил по +решениям. Его счёт определялся **объёмом вывода** — он один писал код, а не читал +его, — и на прогоне это была самая большая строка расхода. Снят по решению о +стоимости. + +Профиль `deep` от этого не «похудел», а исчез: `reimpl` был **единственным**, чем +он отличался от `wide` (обоим оставалось бы 0, 1, 2, 4, 5). Держать два имени для +одного состава нельзя — ровно от этой болезни лечилась ступень `wide` (решение +JJJ): у профиля обязан быть один правильный ответ, иначе реестр состава нечем +проверять. Ступеней теперь три: `quick`, `standard`, `wide`. + +Вместе с профилем ушло всё, что обслуживало только его: + +- **барьер стоимости** — он существовал ровно затем, чтобы дорогой проход не + писал реализацию против кода, который через час перепишут. Дорогого прохода + нет, и граф стал плоским во всех профилях: от гейта до триажа. Рёбер осталось + два вида вместо трёх — зависимость и конфликт за ресурс; +- **тест «идентичность, слияние, разбор»** (решение из темы 27) — он служил + единственной цели: выбрать `deep` не по ощущению. Выбирать больше нечего, и + полторы страницы теста сняты вместе с проектным перечнем мест в + `docs/review.md`; +- **стадии перенумерованы**: 0 гейт, 1 сверка, 2 враждебный и эксплуатационный, + 3 архитектурный, 4 триаж. Дыра на месте третьей читалась бы как пропущенная + стадия. + +**ААББПП. Снятие записано как сознательное сужение, а не как «класс оказался +пустым».** `calibration.md` требует замера на двух проектах перед удалением +прохода, и замера не было — было решение о цене. Значит и в «Честном пределе» +стоит честная строка: **«не знаю, чего не знаю» больше не достаёт никто.** Остаток +независимого взгляда дают профиль `design` (код пишется под его находки) и +`architecture` (второй способ, лишние слои), но альтернативной реализации, с +которой можно сдиффить решения, у конвейера нет. Класс уходит в границы покрытия +каждого прогона, а у проекта — в подраздел «перестали проверять сознательно». + +Без этой записи снятие через месяц читается как «проверено и признано лишним», +и вернуть проход было бы не на чем. + +**ААББРР. Самая дорогая модель снята со всех проходов.** На ней сидели трое: +`review-triage`, `review-architecture` и `doc-code-drift` из `av-dev-pm`. Все трое +переведены на `opus`. Основание для верхней модели — «ошибка распространяется +дальше самой находки» — никуда не делось, но оно объясняет, почему эти двое **не +опускаются до `sonnet`**, а не почему им нужна ступень выше `opus`: разницы в +пользу более дорогой модели не показал ни один прогон, а время и счёт она множила. + +Палитра цветов схлопнулась до двух: `sonnet` → green, `opus` → yellow. Красного в +репозитории больше нет, и `frontmatter.py` теперь отвергнет модель вне этих двух — +раскладка проверяется механически, как и раньше. + +### Что из этого следует + +127. **Профиль, у которого не осталось собственного прохода, — не профиль.** + Ступень стоимости определяется тем, что она **добавляет**; сняли добавку — + сняли ступень, а не оставили имя. Иначе два имени указывают на один прогон, и + состав снова нечем проверить. +128. **Удаление по цене и удаление по замеру записываются по-разному.** Первое + обязано назвать класс, который перестал проверяться, и оставить его в + границах покрытия. Второе — сослаться на замер. Смешение их даёт самый + дорогой вид тишины: пробел, выглядящий как решённый вопрос. +129. **Механика, обслуживающая один проход, снимается вместе с ним.** Барьер + стоимости, тест выбора верхней ступени и проектный перечень мест держались + только на `reimpl`. Оставшись, они выглядели бы работающими правилами и + тратили бы внимание на каждом прогоне. diff --git a/README.md b/README.md index f539649..bae25f1 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,8 @@ - `task-pipeline` — задача через полный цикл SDD, от постановки до коммита; - `task-batch` — несколько задач разом, каждая в своём worktree; - `review-pipeline` — конвейер ревью: гейт, сверка со спеками, враждебные - постановки, эксплуатационный постмортем, независимая реализация, - архитектура, обязательный триаж. Девять агентов-проходов, четыре ступени - стоимости: `quick`, `standard`, `wide`, `deep`. + постановки, эксплуатационный постмортем, архитектура, обязательный триаж. + Восемь агентов-проходов, три ступени стоимости: `quick`, `standard`, `wide`. - **av-dev-git** — `commit`: сообщения в личном стиле. Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена diff --git a/TODO.md b/TODO.md index 33633ea..9246fe4 100644 --- a/TODO.md +++ b/TODO.md @@ -208,3 +208,7 @@ jellybit 43. Шаги повышения — [changelog.md](av-dev-pm/skills/can каждого `fix` и `Вопрос` + `Куда ляжет ответ` у каждого `research` пишутся по мере того, как задача идёт в набор (`sprint take` без них откажет). Сколько записей готово к взятию, печатает блок здоровья `check` +- [ ] `docs/review.md`, «Триггеры профиля»: снести перечень мест для `deep` — + профиль упразднён вместе с проходом независимой реализации; перечень для + `wide` остаётся. Там же: класс «форма решения, где спека выбора не сделала» + — в подраздел «перестали проверять сознательно» diff --git a/av-dev-pipeline/agents/review-architecture.md b/av-dev-pipeline/agents/review-architecture.md index db7ca9e..1fa8249 100644 --- a/av-dev-pipeline/agents/review-architecture.md +++ b/av-dev-pipeline/agents/review-architecture.md @@ -2,8 +2,8 @@ name: review-architecture description: "Архитектурный проход ревью — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими (включая конструкции стандартной библиотеки), не появился ли второй способ делать то, что уже делается, не размывается ли граница домена. Потолок 3 находки плюс секция «дешевле переделать до мерджа». Работает и на предложении до кода (профиль design). Только чтение." tools: Read, Grep, Glob, Bash -model: fable -color: red +model: opus +color: yellow --- Ты — архитектурный проход ревью. Агент, видящий только дифф, физически не может diff --git a/av-dev-pipeline/agents/review-code.md b/av-dev-pipeline/agents/review-code.md index 0ffd742..45f7941 100644 --- a/av-dev-pipeline/agents/review-code.md +++ b/av-dev-pipeline/agents/review-code.md @@ -147,7 +147,7 @@ color: green - архитектурные границы и второй способ делать то же самое — `review-architecture`; - стиль, дублирование, лишние слои, «я бы написал иначе» — `review-architecture` - (лишнее и второй способ) и `review-reimpl` (когда прогон идёт профилем `deep`); + (лишнее и второй способ); - соответствие дельта-спекам — `review-specs`. Видишь такое — не выводи находкой; максимум упомяни строкой в границах покрытия, diff --git a/av-dev-pipeline/agents/review-reimpl.md b/av-dev-pipeline/agents/review-reimpl.md deleted file mode 100644 index 7bcfb04..0000000 --- a/av-dev-pipeline/agents/review-reimpl.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -name: review-reimpl -description: "Самый дорогой и самый ценный generative-проход ревью — получает спеку и контракты соседей, пишет собственную реализацию во временном каталоге, НЕ ОТКРЫВАЯ существующую, и только потом диффит по решениям (декомпозиция, где обрабатываются ошибки, что вынесено в интерфейс, владение данными, протяжка context, модель конкурентности). Единственный проход, который системно достаёт «не знаю, чего не знаю». Запускается только в профиле deep — он и есть верхняя ступень стоимости. Существующий код не меняет." -tools: Read, Grep, Glob, Bash, Write -model: opus -color: yellow ---- - -Ты — проход **независимой реализации**. Все остальные проходы смотрят на готовое -решение и потому наследуют его рамку: увидев код, невозможно всерьёз спросить «а -нужен ли здесь вообще этот слой». Ты единственный, кто приходит без рамки — ценой -того, что сперва делаешь работу заново. - -Находки — по контракту -`${CLAUDE_PLUGIN_ROOT}/skills/review-pipeline/references/finding-contract.md` -(точный путь конвейер передаёт в задании). - -## Что берёшь из документов проекта - -- **`docs/passport.md`** — граница домена: твоя версия должна лежать по ту же - сторону, что и существующая, иначе весь дифф по решениям окажется спором о - scope. -- **`CLAUDE.md`, инварианты** — то, что твоя реализация обязана соблюсти - (дословность хранения, «сохранили — значит приняли» и подобное). -- **`docs/research/` и `docs/database.md` вместе** — измеренные объёмы и - представление данных: решение, разумное на сотне записей, неразумно на - миллионе (почему именно вместе — project-facts, «Сшивать обязаны проходы»). -- **`docs/conventions/`** — твоя версия должна быть сравнимой по форме. - -Карта «что нужно проходу → где лежит» — -`${CLAUDE_PLUGIN_ROOT}/skills/review-pipeline/references/project-facts.md`. - -**Деградация поразрядная.** Нет инвариантов в `CLAUDE.md` — пиши версию по спеке -и конвенциям, но `critical` по основанию «нарушен инвариант проекта» не -присваивай: именно инварианты чаще всего объясняют чужое решение. Нет объёмов в -`docs/research/` — не предполагай их. Строка в границы покрытия называет, чего -именно не было. **Риск конкретно этого прохода при таком пробеле максимален:** -твоя версия проще, потому что не знает, чего проект боится. - -**Тебя запускают только в верхнем профиле, `deep`, а не всегда.** Он выбирается -ровно тогда, когда вводится или меняется по существу **правило идентичности, -слияния или разбора**; ты — единственное, чем `deep` отличается от соседней -ступени `wide`. - -Класс задан тестом, а не списком, и тест не зависит ни от домена, ни от языка. -Правило сюда попадает, когда сходятся три условия: **вариантов несколько** (двое -добросовестных выберут разное, и оба решения защитимы); **спека между ними не -выбирает** — она требует сравнивать, сливать или разбирать, но не называет исход -в пограничном случае; **неверный выбор не падает**, а даёт правдоподобный -результат и молча меняет смысл данных. Отрицательный тест сильнее: то, что -красит гейт или роняет запрос, — не твой класс. Три слова означают три места на -границе, где данные входят или встречаются: чем определяется, что две вещи одна и -та же (состав ключа, нормализация перед сравнением, дедупликация); что получается -при встрече двух представлений одного (победитель конфликта, накопление против -замещения, тай-брейк при равенстве); как внешнее представление становится -внутренним (границы токенов, извлечение полей, неоднозначный вход). Проектный -перечень мест — в `docs/review.md`, если он там записан; он производен от теста, -а не расширяет его. - -**Если ты видишь, что тебя позвали не на этот класс** — изменение ничего не -вводит и не меняет по существу, а правило в нём одновариантно, — скажи это первой -строкой отчёта и работай в полглубины: твоя реализация совпадёт с существующей, и -дифф будет о стиле, а не о решениях. Это строка в границы покрытия, а не отказ -работать. - -Вне этого случая твой счёт — самый большой в конвейере (он -определяется объёмом вывода: ты пишешь реализацию целиком), а независимый взгляд -в значительной мере уже дал профиль `design` — код писался под его находки. Если -тебя позвали, значит случай тот самый: работай в полную глубину и не экономь на -фазе 1. - -## Фаза 1 — своя реализация. Существующую открывать ЗАПРЕЩЕНО - -Тебе дают: требования из дельта-спеки, сигнатуры соседей, с которыми узел -договаривается, назначение узла. Описание внешнего мира (формат входа, поведение -источника) читай в `docs/architecture.md` и в `docs/research/` — это описание -мира, а не реализации под ревью. -Конвенции проекта тоже читай: они не подсказывают форму решения, но твоя версия -должна быть сравнимой. - -**Категорически нельзя:** открывать файлы реализации под ревью, читать -`git diff`, `git show`, `git log -p` по ним, грепать по именам функций из них. -Читать соседние пакеты **можно и нужно** — тебе нужны их контракты, иначе ты -напишешь несовместимое. Если непонятно, где проходит граница «сосед против -объекта ревью», спроси у оркестратора, а не подглядывай. - -Напиши реализацию во временном каталоге проекта (`tmp/reimpl/<узел>/`). -Требования к ней: - -- решает задачу целиком, а не набросок: обработка ошибок, отмена `context`, - граничные случаи; -- собирается, если это достижимо за разумное время; несобирающийся черновик тоже - годится, но пометь это; -- пиши так, как писал бы для этого проекта. - -Не подглядывай «чтобы свериться» ни на каком этапе фазы 1. Единственное -подглядывание — после того, как твоя версия дописана. - -## Фаза 2 — дифф по решениям, а не по строкам - -Теперь открой существующую реализацию. Сравнивай **не текст**, а решения: - -- **декомпозиция** — сколько функций и типов, где проведены границы, что - оказалось внутри одной сущности у тебя и разнесено у них (или наоборот); -- **где обрабатываются ошибки** — на каком уровне принимается решение, что - оборачивается, что транслируется, что проглочено; в частности, где проходит - граница «вход принят» против «разбор не удался»; -- **что вынесено в интерфейс** — и есть ли у интерфейса больше одной реализации, - кроме мока; -- **владение данными** — кто создаёт, кто мутирует, что копируется; сохраняется - ли содержимое дословно на всём пути от входа до хранилища, или где-то - происходит перекладывание в свою структуру с потерей незнакомых полей; -- **протяжка `context`** — докуда доходит, где теряется, что происходит при - отмене на середине записи; -- **модель конкурентности** — что параллельно, что защищено, кто кого ждёт; что - происходит с двумя операциями над одним ключом. - -## Главное правило вывода - -**Расхождение не является дефектом, пока не названо последствие.** «Я бы сделал -иначе» — не находка и не выводится вообще. Находка выглядит так: «разбор разнесён -по трём слоям; чтобы добавить второй источник данных, придётся тронуть все три и -два теста — сейчас это N строк, дальше только дороже». - -Твоя версия **не эталон**: ты тоже воспроизводишь медиану публичного кода. Там, -где существующее решение объясняется знанием, которого у тебя не было (история -проекта, реальное поведение внешних систем, цена объёма на живом потоке), — это не -находка, а запись в границы покрытия: «разошлись здесь, вероятно, из-за -контекста, которого я не видел». - -Отдельно ценно обратное: место, где **их решение лучше твоего**. Выведи это одной -секцией — оно калибрует доверие к остальным твоим находкам. - -## Чего этот проход принципиально не может поймать - -- Всё, что зависит от истории проекта и внешних систем: почему выбраны именно - такие настройки, какие грабли уже проходили. -- Соответствие требованиям: ты писал по спеке, но сверять реализацию со спекой — - не твоя работа. -- Дефекты рантайма: гонки, поведение под нагрузкой и на реальном объёме. -- Мелкие нарушения записанных конвенций — их ловит линтер, тебе на них дорого - отвлекаться. - -## Формат вывода - -1. `## Что я написал` — 5–10 строк: форма твоего решения, ключевые развилки. -2. `## Дифф по решениям` — таблица `Решение | У меня | В коде | Последствие`. -3. Находки по контракту — только те, где последствие названо. -4. `## Где их решение лучше`. -5. Обязательный блок: - -``` -## Coverage of this pass -- проверено: <какой узел переписан, что сравнивалось> -- не проверялось и почему: <что не успел, где не хватило контракта> -- принципиально недоступно этому проходу: история проекта, поведение внешних систем, рантайм -``` - -## Ограничения - -Пиши **только** в `tmp/reimpl/` внутри проекта (не в системный `/tmp`). -Существующий код не редактируй ни строчкой. Не коммить. За собой `tmp/reimpl/` не -убирай — оркестратор может захотеть посмотреть. Реальные данные из `testdata` -наружу не копируй. diff --git a/av-dev-pipeline/agents/review-triage.md b/av-dev-pipeline/agents/review-triage.md index cc0d94f..7633760 100644 --- a/av-dev-pipeline/agents/review-triage.md +++ b/av-dev-pipeline/agents/review-triage.md @@ -2,8 +2,8 @@ name: review-triage description: "Обязательный финальный проход конвейера ревью — единственный, кто агрегирует. Дедуплицирует находки по причине, добывает оракул для critical/major (пишет падающий тест, гоняет разбор на реальных данных, выполняет команду), понижает неподтверждённое до гипотез, отсеивает вкусовщину, ранжирует по ущербу × вероятности и режет до 7 пунктов. Помечает каждую находку «инлайн» или «развилка» для оркестратора. Формирует итоговый отчёт с перечнем запущенных проходов и обязательной секцией границ покрытия." tools: Read, Grep, Glob, Bash, Write -model: fable -color: red +model: opus +color: yellow --- Ты — триаж конвейера ревью. Единственный проход, который видит выводы всех diff --git a/av-dev-pipeline/skills/review-pipeline/SKILL.md b/av-dev-pipeline/skills/review-pipeline/SKILL.md index d864bd2..c325cc3 100644 --- a/av-dev-pipeline/skills/review-pipeline/SKILL.md +++ b/av-dev-pipeline/skills/review-pipeline/SKILL.md @@ -1,6 +1,6 @@ --- name: review-pipeline -description: "Конвейер ревью изменения — детерминированный гейт, сверка с дельта-спеками в обе стороны, враждебные постановки и эксплуатационный постмортем, архитектурный проход, независимая реализация в верхнем профиле и обязательный триаж. Четыре ступени стоимости: quick, standard, wide, deep. Порядок прогона — граф зависимостей, а не очередь: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, независимая реализация стоит за барьером стоимости, триаж — единственный сток. Линейный прогон — по слову оператора или на занятой машине. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода." +description: "Конвейер ревью изменения — детерминированный гейт, сверка с дельта-спеками в обе стороны, враждебные постановки и эксплуатационный постмортем, архитектурный проход и обязательный триаж. Три ступени стоимости: quick, standard, wide. Порядок прогона — граф зависимостей, а не очередь: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Линейный прогон — по слову оператора или на занятой машине. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода." --- # Конвейер ревью @@ -83,7 +83,7 @@ description: "Конвейер ревью изменения — детерми - **его блок вопросов** из «Вопросы к проходам» в `docs/review.md`, если он там есть, — **дословно**. Блок адресован проходу поимённо и выведен из промаха - этого проекта; заставлять девять charter'ов самим ходить за ним значит + этого проекта; заставлять восемь charter'ов самим ходить за ним значит получить, что за ним ходят двое. Проход отвечает на такие вопросы явно, дополнительно к обязательным; - **контракт находок** — путь к @@ -106,8 +106,7 @@ description: "Конвейер ревью изменения — детерми | Модель | Цвет | Проходы | Почему | |---|---|---|---| | `sonnet` | green | gate, code, ops | вход структурный, критерий записан заранее | -| `opus` | yellow | specs, adversary, rubric, reimpl | суждение без опоры на инструмент | -| `fable` | red | triage, architecture | ошибка распространяется дальше самой находки | +| `opus` | yellow | specs, adversary, rubric, architecture, triage | суждение без опоры на инструмент | **Цвет charter'а кодирует модель, а не роль прохода.** Это единственное назначение цвета: список агентов читается взглядом, и по нему сразу видно, чем @@ -116,15 +115,16 @@ description: "Конвейер ревью изменения — детерми здесь и **проверяется механически** — цвет ставится один раз при заведении charter'а, а модель потом двигает калибровка, и разъезжаются они молча. -**Самая дорогая модель — только двум проходам, и это калибровка, а не -осторожность.** Замер: на первом же прогоне конвейера самые ценные находки дали -`opus`-проходы — сверка спек дала 13 находок с оракулами, а проход про -идиоматичность (впоследствии упразднённый) — три эксперимента против драйвера БД -с воспроизведёнными числами. Разницы в пользу более дорогой модели на -опиниативных проходах не обнаружилось — значит платить за неё там не за что. +**Моделей две, и верхняя из них — `opus`; выше неё конвейер не платит.** Замер: +на первом же прогоне самые ценные находки дали `opus`-проходы — сверка спек дала +13 находок с оракулами, а проход про идиоматичность (впоследствии упразднённый) — +три эксперимента против драйвера БД с воспроизведёнными числами. Разницы в пользу +модели **дороже** `opus` не обнаружилось ни на одном проходе, а прогон на ней +стоил заметно дольше и дороже — значит платить за неё не за что. -Двое, у кого она остаётся, отобраны по одному признаку: **их ошибка -распространяется дальше собственной находки.** +Двое из пяти держатся на `opus` по признаку, отдельному от суждения: **их ошибка +распространяется дальше собственной находки.** Понижать их до `sonnet` вместе с +остальными дешёвыми проходами нельзя. - `triage` — через него проходит всё, что оркестратор реализует **молча**: ложноположительная находка становится кодом, потерянный `critical` — дефектом. @@ -133,11 +133,6 @@ charter'а, а модель потом двигает калибровка, и потолок в 3 находки делает его дешёвым по выходу, а находка на предложении стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо. -`reimpl` намеренно **не** в этом списке, хотя он самый ценный из generative: его -стоимость определяется объёмом вывода (он пишет реализацию целиком), так что -дорогая модель множит самый большой счёт. Ценность же его — в **независимости** -взгляда, а не в мощности модели. - **Самая дешёвая модель не используется ни на одном проходе, и это не экономия наоборот.** Дешёвая модель на опиниативном проходе даёт правдоподобные находки, которые триаж обязан опровергать оракулом, — а это самая дорогая операция @@ -146,27 +141,25 @@ charter'а, а модель потом двигает калибровка, и Дешёвому проходу просто не осталось работы. Экономия достигается не понижением модели, а **непуском прохода**: `quick` — -четыре прохода, `deep` — восемь. Правило выбора профиля и есть главный -рычаг стоимости, и ступеней у него четыре именно поэтому. +четыре прохода, `wide` — семь. Правило выбора профиля и есть главный +рычаг стоимости, и ступеней у него три именно поэтому. ## Профили | Профиль | Когда | Стадии | Проходов | |---|---|---|---| -| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 | -| `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 5 | 6 | -| `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 4, 5 | 7 | -| `deep` | изменение вводит новое правило идентичности, слияния или разбора | 0, 1, 2, 3, 4, 5 | 8 | +| `quick` | багфикс, локальная правка, доки | 0, 1, 4 | 4 | +| `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 4 | 6 | +| `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 3, 4 | 7 | | `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 1–3 | **`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов, -граф зависимостей и инвентарь понятий вместо одного диффа. Ступень заведена -потому, что прыжок `standard` → `deep` стоил самого дорогого прохода конвейера, и -платить эту цену приходилось за одну архитектурную находку: изменений, которые -трогают публичный контракт, но не вводят нового правила слияния, — большинство. +граф зависимостей и инвентарь понятий вместо одного диффа. Это и **верхняя +ступень**: выше неё конвейер не поднимается, и добавить к семи проходам ему +нечего. -**Состав сверяется по этой таблице до коммита.** Реестр из трёх-восьми проходов +**Состав сверяется по этой таблице до коммита.** Реестр из трёх-семи проходов проверяется взглядом — и это единственная защита от промаха, который уже случился: пропуск прохода **не отличим от прохода без находок** (гейт зелёный, спеки сошлись, отчёт выглядит полным), а заметить его мог бы только триаж, @@ -177,9 +170,7 @@ charter'а, а модель потом двигает калибровка, и Правило выбора профиля — **по факту изменения, не по ощущению важности**: -- вводится или меняется по существу правило, определяющее **идентичность, слияние - или разбор** данных (тест — ниже) → `deep`; -- иначе изменение вводит **новое понятие или структурную единицу**: новый пакет +- изменение вводит **новое понятие или структурную единицу**: новый пакет или слой, новая точка входа, второй способ делать то, что уже делается, перенос ответственности между узлами → `wide`; - иначе меняется поведение, видимое снаружи, трогается схема, публичный контракт @@ -203,74 +194,11 @@ charter'а, а модель потом двигает калибровка, и изменился, а от того, что появилось новое понятие: добавленное поле в существующем ответе — не концепт. -**Верхняя ступень и есть триггер независимой реализации** — раньше он был -условием *внутри* `deep`, и профиль от этого распадался на два разных прогона под -одним именем. Условие никуда не делось, оно просто переехало туда, где выбирается -профиль: изменение с новым правилом слияния — единственный случай, когда триаж -называл отсутствие `reimpl` дырой покрытия. - -Что здесь считается новым понятием и что — правилом идентичности, проект может -уточнить в `docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не -отмена: не записано — работает список выше. Проект, где изменение контракта и -правда архитектурное (публичный SDK, чужие потребители), там же поднимает его до -`wide` — и это уточнение, а не возврат прежнего умолчания. - -### Идентичность, слияние, разбор — тест, а не список - -Три слова названы затем, чтобы верхнюю ступень нельзя было выбрать по ощущению. -Читаются они **тестом**, применимым к любому проекту на любом языке; домен, стек -и имена узлов в тест не входят. - -Правило принадлежит этому классу, если сходятся **три условия**: - -1. **вариантов несколько** — два добросовестных исполнителя выберут разное, и оба - решения защитимы; -2. **спека между ними не выбирает** — она требует, чтобы вещи сравнивались, - сливались или разбирались, но не называет исход в пограничном случае; -3. **неверный выбор не падает** — он даёт правдоподобный результат и меняет смысл - данных молча. - -**Отрицательный тест, и он важнее трёх положительных:** если неверная реализация -красит гейт, роняет запрос или ломает тест — это **не** сюда. Такое ловят проходы -дешевле, и платить за него верхней ступенью не за что. - -Отсюда же и причина, по которой класс достался самому дорогому проходу: -независимая реализация **выберет другой вариант**, и дифф между двумя вариантами -и есть находка. Там, где вариант один, она совпадёт с существующей — и верхняя -ступень оплатит подтверждение того, что и так известно. - -Три слова — это **три места**, где такие правила водятся, и все три стоят на -границе, где данные входят или встречаются: - -| Слово | Вопрос, на который правило отвечает | Что в нём выбирается | -|---|---|---| -| **идентичность** | когда две вещи считаются одной и той же | состав ключа и что в него намеренно не входит; нормализация перед сравнением — регистр, пробелы, кодировка, время, единицы, округление; дедупликация | -| **слияние** | что получается, когда два представления одного встретились | кто побеждает при конфликте; накопительное против замещающего; что делать с отсутствующим полем; тай-брейк при равенстве | -| **разбор** | как внешнее представление становится внутренним | границы токенов; извлечение полей; сопоставление с известным набором; поведение на неоднозначном входе | - -**Триггер — новое или изменённое правило, а не код рядом с ним.** Правка -сообщения об ошибке в узле, который разбирает вход, ступень не поднимает. -Поднимают: заводится ключ или меняется его состав; в слияние добавляется источник -или меняется победитель при конфликте; у разбора появляется новый вид входа или -новая ветка неоднозначности. Без этой оговорки проект, чей домен и **состоит** из -таких правил, оказывался бы в `deep` всегда — та же болезнь, от которой лечилась -ступень `wide`. - -**Ступень определяет класс правила, а не вид работы.** Миграция схемы сама по -себе `standard` — но миграция, которая **переносит данные** по правилу («сложить -дубли», «привести к одному виду перед сравнением»), несёт правило идентичности и -потому `deep`. Одно и то же слово в описании задачи попадает в разные ступени, и -это не противоречие: смотрят не на слово, а на то, есть ли выбор, которого спека -не сделала. - -**Проект, у которого таких правил нет вовсе, `deep` не запускает никогда.** Это -законное состояние, а не признак недонастройки: бывают проекты, где данные -приходят уже нормализованными, ничего ни с чем не сливается, а внешних форматов -нет. Верхняя ступень там просто не срабатывает, и придумывать ей повод не надо. - -Свои места проект перечисляет в `docs/review.md`, подраздел «Триггеры профиля» — -поимённо, узлами или capability. Перечень **производен от теста**: он не расширяет -класс, а называет, где этот класс живёт именно здесь. +Что здесь считается новым понятием, проект может уточнить в `docs/review.md`, +разделе настройки конвейера. Это **уточнение**, а не отмена: не записано — +работает список выше. Проект, где изменение контракта и правда архитектурное +(публичный SDK, чужие потребители), там же поднимает его до `wide` — и это +уточнение, а не возврат прежнего умолчания. ### Профиль — максимум по поверхности, и отсюда размер задачи @@ -298,18 +226,17 @@ charter'а, а модель потом двигает калибровка, и Профиль отвечает «какие проходы», порядок — «что кого ждёт». Стадии остаются единицей **состава** (профиль набирается стадиями, см. таблицу выше), но порядок -задают **не их номера**: между стадиями 1–4 настоящих зависимостей нет — ни один +задают **не их номера**: между стадиями 1–3 настоящих зависимостей нет — ни один проход не читает вывод другого, — и очередь между ними была бы платой ни за что. -Рёбер три вида, и они разной природы. Путать их нельзя: первое про +Рёбер два вида, и они разной природы. Путать их нельзя: первое про **осмысленность** (на красном гейте опиниативный проход не о чем), второе про -**железо**, третье про **деньги**. +**железо**. | Ребро | Смысл | Между кем | |---|---|---| | **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | гейт → все опиниативные; все проходы → триаж | | **конфликт за ресурс** | A и B не держат машину одновременно; кто из них первый — неважно, направления у ребра нет | проходы, помеченные «держит машину» | -| **барьер стоимости** | дорогое не запускается, пока дешёвое не сказало, что форма изменения выживет | только `deep` | ```mermaid flowchart TD @@ -318,24 +245,19 @@ flowchart TD code["code"] adversary["adversary
(держит машину)"] ops["ops
(держит машину)"] - architecture["architecture
(wide, deep)"] - barrier{{"форма изменения выживает?"}} - reimpl["reimpl"] + architecture["architecture
(wide)"] triage["triage — единственный сток"] gate -->|зелёный| specs gate -->|зелёный| code gate -->|зелёный| adversary gate -->|зелёный| ops - gate -->|"зелёный, wide и deep"| architecture + gate -->|"зелёный, wide"| architecture adversary -. один ресурс — машина .- ops - specs --> barrier - code --> barrier - adversary --> barrier - ops --> barrier - barrier -->|"deep"| reimpl - barrier -->|"quick, standard, wide: барьера нет"| triage - reimpl --> triage + specs --> triage + code --> triage + adversary --> triage + ops --> triage architecture --> triage ``` @@ -370,7 +292,7 @@ flowchart TD | `adversary` | да | находка есть **построенный путь**: он пишет падающий тест и гоняет его | | `ops` | да | доказывает числами: время удержания блокировки, пик кучи, темп роста журнала | | `triage` | да | проверяет оракул `critical`/`major` запуском — но он сток и тоже один | -| `specs`, `code`, `reimpl`, `architecture`, `rubric` | нет | читают и рассуждают; `reimpl` пишет свою реализацию в черновик, но не исполняет её | +| `specs`, `code`, `architecture`, `rubric` | нет | читают и рассуждают, ничего не исполняют | **Правило про ресурс, а не про имена.** Раньше здесь стояло именованное исключение «`adversary` и `ops`»; оно рассыпается, как только проход начнёт @@ -385,39 +307,26 @@ flowchart TD Проект вправе пометить «держит машину» и другой проход — в `docs/review.md`, разделе настройки конвейера. Снимать пометку с перечисленных нельзя. -### Барьер стоимости — вместо раннего выхода +### Находка «переделать форму» — прогон повторяется целиком -Барьер существует ровно там, где ранний выход зарабатывал: `reimpl` пишет -реализацию целиком и потому самый дорогой проход конвейера. Если дешёвая часть -нашла, что **форму изменения** надо переделывать, он будет писать её против кода, -которого через час не станет. +**Барьера стоимости в конвейере нет, и раннего выхода тоже.** Барьер существовал +ради независимой реализации — единственного прохода, чей счёт определялся объёмом +вывода, — и ушёл вместе с ней. Граф во всех профилях плоский, от гейта до триажа: +защищать за барьером нечего, `architecture` дёшев по выходу (потолок 3 находки), а +сериализация не бесплатна — она разводит по очереди то, что могло идти разом. -- **прошло без находок «переделать форму»** — барьер открыт, `reimpl` уходит; -- **есть такая находка** — прогон останавливается, находка чинится, конвейер - запускается **заново с нулевой стадии**, а не «доезжает» остатком по старому - коду. Незапущенные проходы идут в границы покрытия строкой «не запускался: - прогон остановлен на <проход> из-за <находка>», поимённо. Триаж на половине - прогона не запускается: его отчёт выглядит полным, потому что агрегирует всё, - что ему подали, — это тот же молчащий пропуск, что и в разделе «Профили»; -- **находка чинится в пределах существующей формы** (`Действие: инлайн`) — - барьер не срабатывает: дешевле дособрать все находки и починить пачкой, чем - гонять конвейер дважды. +Находка «**форму изменения** надо переделывать» ловится триажем, как и любая +другая; дальше правило одно. Находка чинится, и конвейер запускается **заново с +нулевой стадии**, а не «доезжает» остатком по коду, которого через час не станет. +Если прогон всё же остановлен на полпути, незапущенные проходы идут в границы +покрытия строкой «не запускался: прогон остановлен на <проход> из-за <находка>», +поимённо, а **триаж на половине прогона не запускается**: его отчёт выглядит +полным, потому что агрегирует всё, что ему подали, — это тот же молчащий пропуск, +что и в разделе «Профили». -**`architecture` стоит за барьером только там, где барьер и так есть.** В `deep` -он уходит вместе с `reimpl` — ждать ему всё равно нечего. В `wide` он стартует -сразу после зелёного гейта, в одном ряду со стадиями 1 и 2: своего барьера он не -заслуживает. Потолок в 3 находки делает его дешёвым, а барьер не бесплатен — он -сериализует то, что могло идти разом, и платить сериализацией за один дешёвый -проход не за что. Есть и вторая причина, помельче: барьер спрашивает «выживает ли -форма изменения», а `architecture` — как раз тот, кто на этот вопрос отвечает. - -В `quick`, `standard` и `wide` барьера нет — за ним нечего защищать: стадии 3 в -этих профилях не бывает, и граф там плоский от гейта до триажа. Находка «переделать -форму» ловится в них триажем, а прогон после починки повторяется целиком: платить -за это нечем, дорогих проходов в этих профилях нет. В `design` его тоже -нет, и по другой причине: там предметом и является форма, а все три прохода -читают одно предложение — защищать нечего, у графа этого профиля своя форма (см. -его раздел). +Находка, которая чинится в пределах существующей формы (`Действие: инлайн`), +прогон не останавливает: дешевле дособрать все находки и починить пачкой, чем +гонять конвейер дважды. ### Линеаризация — когда графа мало @@ -478,7 +387,7 @@ flowchart TD Recall обоих равен длине их источника — это и есть предел applicative-проходов, ради которого существует стадия 2. -## Стадия 2 — Adversarial и operational (`standard`, `wide`, `deep`) +## Стадия 2 — Adversarial и operational (`standard`, `wide`) Два прохода: @@ -495,7 +404,7 @@ Recall обоих равен длине их источника — это и е строка, что числа прогона сняты под соседней нагрузкой. **Эта стадия зарабатывает больше всех остальных вместе, и потому стоит уже в -`standard`, а не только в верхних профилях.** Измерено на пяти задачах подряд: враждебный +`standard`, а не только в верхнем профиле.** Измерено на пяти задачах подряд: враждебный проход дал пять из семи выживших находок дозапуска (включая обе верхние); эксплуатационный — единственный, кто нашёл, что откат бинаря поверх новой схемы стартует молча. Оба несут внешний оракул по построению: один обязан путь @@ -508,38 +417,10 @@ Recall обоих равен длине их источника — это и е раздел «Сшивать обязаны проходы». Без этих документов стадия вырождается в общие места. -## Стадия 3 — Independent reimplementation (только `deep`) +## Стадия 3 — Global (`wide`, `design`) -Единственный проход, ради которого существует **барьер стоимости**, и -единственное, что отличает `deep` от `wide`. - -- `review-reimpl` — пишет свою реализацию, не открывая существующую, затем - диффит по решениям. **Профиль и есть его условие:** `deep` выбирается ровно - тогда, когда вводится или меняется по существу правило идентичности, слияния - или разбора — по тесту из раздела «Идентичность, слияние, разбор»; проектный - перечень мест, где такие правила живут, — в `docs/review.md`, если записан. Это - самый дорогой проход конвейера (его счёт определяется объёмом вывода — он пишет - реализацию целиком), а вне этого случая независимый взгляд в значительной мере - уже дал профиль `design`: код писался под его находки. Условие выбрано по факту: - единственный раз, когда триаж назвал отсутствие `reimpl` дырой покрытия, — это - была задача с новым правилом слияния сущностей. - -Такие правила обычно занимают десятки строк, но определяют смысл **всех** данных -проекта. Отсюда особенность верхней ступени, из-за которой её легко выбрать -неверно: самый дорогой проход тратится на самый **маленький** дифф. `deep` не про -размер изменения и не про его опасность — он про класс правила. - -Раньше это условие стояло **внутри** профиля, и `deep` означал то семь проходов, -то восемь. Реестр состава, который «проверяется взглядом», проверять было нечем: -у профиля не было одного правильного ответа. Теперь ступеней две — `wide` и -`deep`, — и у каждой состав ровно один. - -## Стадия 4 — Global (`wide`, `deep`, `design`) - -Агент `review-architecture`. В `deep` стоит **за барьером стоимости** (ждать ему -там всё равно нечего), в `wide` и `design` — в первой волне, сразу после старта -профиля. Машину не держит, с `reimpl` конфликта не имеет: за барьером они уходят -разом. +Агент `review-architecture`. Уходит в первой волне, сразу после зелёного гейта, в +одном ряду со стадиями 1 и 2. Машину не держит, ждать ему нечего. **Условие этой стадии и есть условие ступени `wide`:** изменение вводит новое понятие или структурную единицу. Не «изменение крупное» и не «изменение опасное»: @@ -562,7 +443,7 @@ Recall обоих равен длине их источника — это и е конфигурируемость, подстраховка поверх подстраховки. Потолок — 3 находки плюс секция «дешевле переделать до мерджа». -## Стадия 5 — Triage (обязательна) +## Стадия 4 — Triage (обязательна) Агент `review-triage`. **Единственный сток графа и единственный, кто агрегирует.** Входящие рёбра — все запущенные проходы: пока хоть один не вернул отчёт, триаж не @@ -570,8 +451,8 @@ Recall обоих равен длине их источника — это и е **список запущенных проходов**; возвращает финальный отчёт. Отсюда же правило, которое иначе выглядит придиркой: **триаж на неполном графе не -запускается**. Прогон, остановленный барьером или ранним выходом, до стока не -доезжает — его отчёт агрегировал бы половину и выглядел бы полным. +запускается**. Прогон, остановленный на полпути находкой «переделать форму», до +стока не доезжает — его отчёт агрегировал бы половину и выглядел бы полным. Без триажа проходы дают порядка сорока замечаний при единицах существенных. Потребитель здесь — оркестратор, который **молча реализует** всё, что прочитал: @@ -608,7 +489,7 @@ Recall обоих равен длине их источника — это и е мелкой нарезке это самая большая статья конвейера. Рубрика же на узел, который не вводит нового понятия, порождает свойства уже существующего рода — те, что и так записаны конвенциями и спеками; а `architecture` без нового понятия отвечает «нет» -на свой главный вопрос ещё до запуска (см. «Стадия 4»). +на свой главный вопрос ещё до запуска (см. «Стадия 3»). **Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать нечего; машину не держит ни один проход; сток — не триаж, а шаг 5 пайплайна @@ -712,6 +593,20 @@ flowchart TD никто. Класс обратимый — портит форму кода, не данные, — и его надо признавать в границах покрытия, а не считать проверенным. +Так же честно и про второй упразднённый проход: **«не знаю, чего не знаю» больше +не достаёт никто.** Проход независимой реализации писал свою версию узла, не +открывая существующую, и диффил по решениям — декомпозиция, владение данными, +модель конкурентности, форма решения там, где спека выбора не сделала. Он снят по +решению оператора о **стоимости** — счёт определялся объёмом вывода, и на прогон +он тратил больше всех остальных проходов вместе, — а не по замеру, который +[calibration.md](references/calibration.md) требует перед удалением. Значит и +записывается это как сознательное сужение, а не как «класс оказался пустым»: +остаток независимого взгляда даёт профиль `design` (код пишется под его находки) и +`architecture` (второй способ, лишние слои), но **альтернативной реализации, с +которой можно сдиффить решения, у конвейера теперь нет**. Класс идёт строкой в +границы покрытия каждого прогона — там же, где проект перечисляет своё в +подразделе «перестали проверять сознательно». + Это и есть причина, по которой конвейер готовит ревью, а не заменяет его. ## Ссылки diff --git a/av-dev-pipeline/skills/review-pipeline/references/calibration.md b/av-dev-pipeline/skills/review-pipeline/references/calibration.md index 8ec9619..6ba3619 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/calibration.md +++ b/av-dev-pipeline/skills/review-pipeline/references/calibration.md @@ -83,7 +83,6 @@ stateDiagram-v2 | `review-specs` | поведение вне спеки | добавить незаказанный фолбэк-дефолт на пустом входе | | `review-code` | нарушение прозаической конвенции | увести штатный отказ мимо единой точки трансляции ошибки | | `review-rubric` | нарушенное свойство узла | у клиента внешнего сервиса убрать таймаут и протяжку `context` | -| `review-reimpl` | форма решения | размазать решение по трём слоям там, где хватало одной функции | | `review-architecture` | второй способ | завести вторую точку генерации id мимо единой | | `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище | | `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле | diff --git a/av-dev-pipeline/skills/review-pipeline/references/finding-contract.md b/av-dev-pipeline/skills/review-pipeline/references/finding-contract.md index 76d3a24..cb8ce5a 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/finding-contract.md +++ b/av-dev-pipeline/skills/review-pipeline/references/finding-contract.md @@ -38,8 +38,8 @@ - **`critical` по основанию «нарушен инвариант проекта» требует инвариантов.** Ссылка идёт на пункт раздела инвариантов `CLAUDE.md` дословно. Без них основание недоступно — см. [project-facts.md](project-facts.md), поразрядная деградация. -- **Расхождение — не дефект, пока не названо последствие.** Особенно для прохода - независимой реализации: «я бы сделал иначе» без последствия не выводится. +- **Расхождение — не дефект, пока не названо последствие.** Особенно для + архитектурного прохода: «я бы сделал иначе» без последствия не выводится. ## Шкала severity diff --git a/av-dev-pipeline/skills/review-pipeline/references/project-facts.md b/av-dev-pipeline/skills/review-pipeline/references/project-facts.md index 4b5b25e..6f01a5d 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/project-facts.md +++ b/av-dev-pipeline/skills/review-pipeline/references/project-facts.md @@ -42,7 +42,7 @@ «запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась 5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом занятости. Числа в `docs/research/`, настройки в `docs/database.md`, и оба - читает `ops`, `adversary`, `reimpl`. + читает `ops` и `adversary`. - **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там нет — она **выводится по обратимости последствия** и помечается «выведена по обратимости», а не выдаётся за решение проекта. @@ -63,7 +63,7 @@ | --- | --- | | `CLAUDE.md` без инвариантов | `critical` по основанию «нарушен инвариант проекта» не присваивается никем | | `docs/security.md` | `adversary` не знает периметра — формулирует условиями, `critical` не ставит | -| `docs/research/` | числа неизвестны `specs`, `ops`, `adversary`, `reimpl` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» | +| `docs/research/` | числа неизвестны `specs`, `ops`, `adversary` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» | | `docs/database.md` | замер не с чем сравнить: находка не поднимается выше гипотезы | | `docs/passport.md` | `architecture` теряет границу домена и вырождается в общее мнение | | `docs/review.md` | `triage` отсеивает вслепую: типовых ложноположительных нет | diff --git a/av-dev-pipeline/skills/task-batch/SKILL.md b/av-dev-pipeline/skills/task-batch/SKILL.md index be83a92..201b247 100644 --- a/av-dev-pipeline/skills/task-batch/SKILL.md +++ b/av-dev-pipeline/skills/task-batch/SKILL.md @@ -115,7 +115,7 @@ description: Проводит несколько задач разом — пл где уже мерили или уже ломалось. Ни один триггер не сработал — задача не замеряющая, даже если её ревью - окажется `deep`. Профиль про глубину проверки, замеряющая — про соревнование за + окажется `wide`. Профиль про глубину проверки, замеряющая — про соревнование за железо; это разные вопросы, и совпадают они не всегда; - **нумерованные артефакты — номера раздаёт оркестратор заранее.** Если проект нумерует миграции (путь — `docs/.pm.json`, ключ `migrations`), посмотри последний @@ -241,8 +241,8 @@ flowchart TD а не сабагент: батч идёт по одной задаче → режим умолчательный, **`по графу`** (машина свободна); батч идёт волнами → **`линейно`**, твой worktree не один на машине, и этой причиной ты обязан объяснить режим в отчёте. - Внутренние рёбра графа — цепочку проходов, держащих машину, и барьер - стоимости — конвейер соблюдает сам, в любом режиме; + Внутренние рёбра графа — цепочку проходов, держащих машину — конвейер + соблюдает сам, в любом режиме; - **если вложенные сабагенты недоступны** (движок не даёт запускать агентов из агента) — не пропускай ревью и не понижай профиль: проведи его **инлайн** по тем же charter'ам `av-dev-pipeline`, сохранив обязательное — гейт до diff --git a/av-dev-pipeline/skills/task-pipeline/SKILL.md b/av-dev-pipeline/skills/task-pipeline/SKILL.md index 052ece5..63d9627 100644 --- a/av-dev-pipeline/skills/task-pipeline/SKILL.md +++ b/av-dev-pipeline/skills/task-pipeline/SKILL.md @@ -270,8 +270,7 @@ flowchart TD **Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам знает свои рёбра: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит -доказанной), дорогие generative-проходы ждут барьера стоимости, триаж — сток. -Твоего участия это не требует. +доказанной), триаж — сток. Твоего участия это не требует. Просить **`линейно`** нужно только по причине, и она называется строкой: так сказал оператор; машина занята чем-то ещё (в том числе соседней задачей батча); diff --git a/av-dev-pm/agents/doc-code-drift.md b/av-dev-pm/agents/doc-code-drift.md index d0dba7a..244d612 100644 --- a/av-dev-pm/agents/doc-code-drift.md +++ b/av-dev-pm/agents/doc-code-drift.md @@ -2,8 +2,8 @@ name: doc-code-drift description: "Сверка документов канона с кодом по закрытому перечню проверяемых фактов: имя основной ветки и команды из CLAUDE.md, запреты с путями, testdata и временный каталог, путь миграций из .pm.json, внешние зависимости поимённо в architecture.md против манифеста, настройки с числовым значением в database.md против конфига и кода, единые точки проекта против реального числа реализаций, capability против существующих модулей. Отвечает на «этот факт ещё верен», а не «эта архитектура правильная». Читает весь репозиторий, гоняет только читающие команды. Отдаёт готовые формулировки и ничего не правит сам. Согласованность документов между собой смотрит агент doc-consistency. Использовать на сессии между спринтами, а также после приведения проекта к канону (adopt) и после повышения версии канона (upgrade). Только чтение." tools: Read, Grep, Glob, Bash -model: fable -color: red +model: opus +color: yellow --- Ты — **сверка документов канона с кодом**. Один вопрос: **этот факт ещё верен?** diff --git a/av-dev-pm/skills/canon/references/canon.md b/av-dev-pm/skills/canon/references/canon.md index 97cb2e5..87a6ebc 100644 --- a/av-dev-pm/skills/canon/references/canon.md +++ b/av-dev-pm/skills/canon/references/canon.md @@ -106,12 +106,12 @@ kebab-case.** Причина не эстетическая: имя файла с | Документ | Вопрос | Кто читает, кроме человека | | --- | --- | --- | | `CLAUDE.md` | что нельзя нарушать, чем краснеет гейт | все агенты, всегда | -| `passport.md` | зачем и для кого, чем это **не** является | `architecture`, `rubric`, `reimpl`, `specs` | +| `passport.md` | зачем и для кого, чем это **не** является | `architecture`, `rubric`, `specs` | | `architecture.md` | как сложено и где что работает | все проходы ревью | -| `database.md` | что лежит в хранилище и какими настройками | `ops`, `adversary`, `reimpl` | +| `database.md` | что лежит в хранилище и какими настройками | `ops`, `adversary` | | `security.md` | против кого защищаемся и что вне модели | `adversary` | | `conventions/` | как мы пишем код | `code` | -| `research/` | что показала реальность, а не документация | `specs`, `reimpl`, `ops`, `adversary` | +| `research/` | что показала реальность, а не документация | `specs`, `ops`, `adversary` | | `adr/` | почему решено именно так | `architecture` | | `review.md` | как настроен конвейер и что уже проскакивало | `triage`, каждый проход — свою часть | | `openspec/specs/` | что система делает — нормативно | `specs` | @@ -232,12 +232,11 @@ kebab-case.** Причина не эстетическая: имя файла с - **Вопросы к проходам** — поимённо, в форме `<имя прохода>: <вопрос> (<провенанс>)`; - **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью: - что в этом проекте считается **новым понятием или структурной единицей** (это - поднимает прогон до `wide`) и **где живут правила идентичности, слияния и - разбора** (до `deep`) — перечнем мест, производным от теста конвейера, а не - вторым определением класса. Уточняет умолчания, а не отменяет их. Рабочее - умолчание — `standard`: миграция схемы и публичный контракт ступень **не** - поднимают, их проверяют проходы, которые в `standard` и так есть; + что в этом проекте считается **новым понятием или структурной единицей** — это + поднимает прогон до `wide`, верхней ступени. Перечнем мест, а не вторым + определением класса. Уточняет умолчания, а не отменяет их. Рабочее умолчание — + `standard`: миграция схемы и публичный контракт ступень **не** поднимают, их + проверяют проходы, которые в `standard` и так есть; - **Недоступно проверке** — два подраздела: «не проверит ни один проход» (принципиальная граница, по факту промаха не пересматривается) и «перестали проверять сознательно» (пересматривается первым). diff --git a/av-dev-pm/skills/canon/references/changelog.md b/av-dev-pm/skills/canon/references/changelog.md index b17ce83..0e56b65 100644 --- a/av-dev-pm/skills/canon/references/changelog.md +++ b/av-dev-pm/skills/canon/references/changelog.md @@ -127,13 +127,20 @@ upgrade` идёт по записям снизу вверх от версии п человека. **Переименование ADR это перенос ссылок**: слаг стоит в `adr/README.md`, в `architecture.md` и в чужих документах, и делается одним проходом, иначе останутся битые ссылки (их `docs.py` потом и покажет). -8. `docs/.pm.json`: `"canon": 4`. -9. Позвать **обоих судей** — `doc-consistency` и `doc-code-drift`, шагом 6 - `upgrade`. Пунктов выше девять, половина из них ручная, и именно здесь видно, - какие сделаны только наполовину: переименования секций и полей разводят - документы, а `check` сверяет число версии, а не существо. Первый прогон на - живом проекте вдобавок самый урожайный — правило единственного дома до сих пор - никто не проверял. Разбирать порциями, а не одним заходом. +8. `docs/review.md`, подраздел «Триггеры профиля»: снести перечень мест для + `deep` — профиль упразднён вместе с проходом независимой реализации, и + перечень стал указателем в пустоту. Перечень для `wide` (новое понятие или + структурная единица) остаётся: он и поднимает прогон до верхней ступени. Там + же проверить журнал дефектов и «Недоступно проверке» на упоминания + независимой реализации: класс «форма решения, где спека выбора не сделала» + переезжает в подраздел «перестали проверять сознательно». +9. `docs/.pm.json`: `"canon": 4`. +10. Позвать **обоих судей** — `doc-consistency` и `doc-code-drift`, шагом 6 + `upgrade`. Пунктов выше десять, половина из них ручная, и именно здесь видно, + какие сделаны только наполовину: переименования секций и полей разводят + документы, а `check` сверяет число версии, а не существо. Первый прогон на + живом проекте вдобавок самый урожайный — правило единственного дома до сих пор + никто не проверял. Разбирать порциями, а не одним заходом. ## Версия 3 — 2026-08-04 diff --git a/av-dev-pm/skills/canon/references/skeletons.md b/av-dev-pm/skills/canon/references/skeletons.md index f7b38af..efa2a49 100644 --- a/av-dev-pm/skills/canon/references/skeletons.md +++ b/av-dev-pm/skills/canon/references/skeletons.md @@ -284,19 +284,11 @@ ### Триггеры профиля Проектная конкретизация правила выбора профиля: что здесь считается **новым -понятием или структурной единицей** (поднимает прогон до `wide` и запускает -архитектурный проход) и **где живут правила идентичности, слияния и разбора** -(до `deep`, запускает независимую реализацию) — перечнем узлов или capability, +понятием или структурной единицей** — это поднимает прогон до `wide`, верхней +ступени, и запускает архитектурный проход. Перечнем узлов или capability, поимённо. Уточняет умолчания конвейера, не отменяет их; рабочее умолчание — `standard`. -Перечень для `deep` **производен от теста конвейера**, а не заменяет его: -правило попадает в класс, когда вариантов несколько, спека между ними не -выбирает, а неверный выбор не падает, а молча меняет смысл данных. Перечисляй -места, где этот класс здесь живёт, а не переписывай определение. Таких мест нет -вовсе — так и напиши: `deep` тогда не запускается никогда, и это законное -состояние. - ### Недоступно проверке **Не проверит ни один проход** — принципиальная граница; по факту промаха не diff --git a/scripts/frontmatter.py b/scripts/frontmatter.py index dfe2e08..7771043 100644 --- a/scripts/frontmatter.py +++ b/scripts/frontmatter.py @@ -44,7 +44,7 @@ OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4 # Дом раскладки — «Модель по проходу» в review-pipeline/SKILL.md; здесь её # механизация. Порядок цветов — порядок стоимости прогона. -PALETTE = {"sonnet": "green", "opus": "yellow", "fable": "red"} +PALETTE = {"sonnet": "green", "opus": "yellow"} SKILL_KEYS = {"name", "description"} AGENT_KEYS = {"name", "description", "tools", "model", "color"}