стоимость ревью: снят проход независимой реализации и самая дорогая модель
Прогоны стали долгими, а счёт в токенах заметным. Разбор шёл не по находкам, а по статьям расхода. Две названы прямо: убрать 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) <noreply@anthropic.com>
This commit is contained in:
@@ -2258,3 +2258,73 @@ dev-skills — **маркетплейс плагинов**: скилл комм
|
|||||||
126. **Снятое слово называется вместе с заменой и остаётся записанным.** Убрать
|
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`. Оставшись, они выглядели бы работающими правилами и
|
||||||
|
тратили бы внимание на каждом прогоне.
|
||||||
|
|||||||
@@ -29,9 +29,8 @@
|
|||||||
- `task-pipeline` — задача через полный цикл SDD, от постановки до коммита;
|
- `task-pipeline` — задача через полный цикл SDD, от постановки до коммита;
|
||||||
- `task-batch` — несколько задач разом, каждая в своём worktree;
|
- `task-batch` — несколько задач разом, каждая в своём worktree;
|
||||||
- `review-pipeline` — конвейер ревью: гейт, сверка со спеками, враждебные
|
- `review-pipeline` — конвейер ревью: гейт, сверка со спеками, враждебные
|
||||||
постановки, эксплуатационный постмортем, независимая реализация,
|
постановки, эксплуатационный постмортем, архитектура, обязательный триаж.
|
||||||
архитектура, обязательный триаж. Девять агентов-проходов, четыре ступени
|
Восемь агентов-проходов, три ступени стоимости: `quick`, `standard`, `wide`.
|
||||||
стоимости: `quick`, `standard`, `wide`, `deep`.
|
|
||||||
- **av-dev-git** — `commit`: сообщения в личном стиле.
|
- **av-dev-git** — `commit`: сообщения в личном стиле.
|
||||||
|
|
||||||
Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена
|
Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена
|
||||||
|
|||||||
@@ -208,3 +208,7 @@ jellybit 43. Шаги повышения — [changelog.md](av-dev-pm/skills/can
|
|||||||
каждого `fix` и `Вопрос` + `Куда ляжет ответ` у каждого `research` пишутся
|
каждого `fix` и `Вопрос` + `Куда ляжет ответ` у каждого `research` пишутся
|
||||||
по мере того, как задача идёт в набор (`sprint take` без них откажет).
|
по мере того, как задача идёт в набор (`sprint take` без них откажет).
|
||||||
Сколько записей готово к взятию, печатает блок здоровья `check`
|
Сколько записей готово к взятию, печатает блок здоровья `check`
|
||||||
|
- [ ] `docs/review.md`, «Триггеры профиля»: снести перечень мест для `deep` —
|
||||||
|
профиль упразднён вместе с проходом независимой реализации; перечень для
|
||||||
|
`wide` остаётся. Там же: класс «форма решения, где спека выбора не сделала»
|
||||||
|
— в подраздел «перестали проверять сознательно»
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
name: review-architecture
|
name: review-architecture
|
||||||
description: "Архитектурный проход ревью — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими (включая конструкции стандартной библиотеки), не появился ли второй способ делать то, что уже делается, не размывается ли граница домена. Потолок 3 находки плюс секция «дешевле переделать до мерджа». Работает и на предложении до кода (профиль design). Только чтение."
|
description: "Архитектурный проход ревью — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими (включая конструкции стандартной библиотеки), не появился ли второй способ делать то, что уже делается, не размывается ли граница домена. Потолок 3 находки плюс секция «дешевле переделать до мерджа». Работает и на предложении до кода (профиль design). Только чтение."
|
||||||
tools: Read, Grep, Glob, Bash
|
tools: Read, Grep, Glob, Bash
|
||||||
model: fable
|
model: opus
|
||||||
color: red
|
color: yellow
|
||||||
---
|
---
|
||||||
|
|
||||||
Ты — архитектурный проход ревью. Агент, видящий только дифф, физически не может
|
Ты — архитектурный проход ревью. Агент, видящий только дифф, физически не может
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ color: green
|
|||||||
- архитектурные границы и второй способ делать то же самое —
|
- архитектурные границы и второй способ делать то же самое —
|
||||||
`review-architecture`;
|
`review-architecture`;
|
||||||
- стиль, дублирование, лишние слои, «я бы написал иначе» — `review-architecture`
|
- стиль, дублирование, лишние слои, «я бы написал иначе» — `review-architecture`
|
||||||
(лишнее и второй способ) и `review-reimpl` (когда прогон идёт профилем `deep`);
|
(лишнее и второй способ);
|
||||||
- соответствие дельта-спекам — `review-specs`.
|
- соответствие дельта-спекам — `review-specs`.
|
||||||
|
|
||||||
Видишь такое — не выводи находкой; максимум упомяни строкой в границах покрытия,
|
Видишь такое — не выводи находкой; максимум упомяни строкой в границах покрытия,
|
||||||
|
|||||||
@@ -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`
|
|
||||||
наружу не копируй.
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
name: review-triage
|
name: review-triage
|
||||||
description: "Обязательный финальный проход конвейера ревью — единственный, кто агрегирует. Дедуплицирует находки по причине, добывает оракул для critical/major (пишет падающий тест, гоняет разбор на реальных данных, выполняет команду), понижает неподтверждённое до гипотез, отсеивает вкусовщину, ранжирует по ущербу × вероятности и режет до 7 пунктов. Помечает каждую находку «инлайн» или «развилка» для оркестратора. Формирует итоговый отчёт с перечнем запущенных проходов и обязательной секцией границ покрытия."
|
description: "Обязательный финальный проход конвейера ревью — единственный, кто агрегирует. Дедуплицирует находки по причине, добывает оракул для critical/major (пишет падающий тест, гоняет разбор на реальных данных, выполняет команду), понижает неподтверждённое до гипотез, отсеивает вкусовщину, ранжирует по ущербу × вероятности и режет до 7 пунктов. Помечает каждую находку «инлайн» или «развилка» для оркестратора. Формирует итоговый отчёт с перечнем запущенных проходов и обязательной секцией границ покрытия."
|
||||||
tools: Read, Grep, Glob, Bash, Write
|
tools: Read, Grep, Glob, Bash, Write
|
||||||
model: fable
|
model: opus
|
||||||
color: red
|
color: yellow
|
||||||
---
|
---
|
||||||
|
|
||||||
Ты — триаж конвейера ревью. Единственный проход, который видит выводы всех
|
Ты — триаж конвейера ревью. Единственный проход, который видит выводы всех
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: review-pipeline
|
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`, если он там
|
- **его блок вопросов** из «Вопросы к проходам» в `docs/review.md`, если он там
|
||||||
есть, — **дословно**. Блок адресован проходу поимённо и выведен из промаха
|
есть, — **дословно**. Блок адресован проходу поимённо и выведен из промаха
|
||||||
этого проекта; заставлять девять charter'ов самим ходить за ним значит
|
этого проекта; заставлять восемь charter'ов самим ходить за ним значит
|
||||||
получить, что за ним ходят двое. Проход отвечает на такие вопросы явно,
|
получить, что за ним ходят двое. Проход отвечает на такие вопросы явно,
|
||||||
дополнительно к обязательным;
|
дополнительно к обязательным;
|
||||||
- **контракт находок** — путь к
|
- **контракт находок** — путь к
|
||||||
@@ -106,8 +106,7 @@ description: "Конвейер ревью изменения — детерми
|
|||||||
| Модель | Цвет | Проходы | Почему |
|
| Модель | Цвет | Проходы | Почему |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `sonnet` | green | gate, code, ops | вход структурный, критерий записан заранее |
|
| `sonnet` | green | gate, code, ops | вход структурный, критерий записан заранее |
|
||||||
| `opus` | yellow | specs, adversary, rubric, reimpl | суждение без опоры на инструмент |
|
| `opus` | yellow | specs, adversary, rubric, architecture, triage | суждение без опоры на инструмент |
|
||||||
| `fable` | red | triage, architecture | ошибка распространяется дальше самой находки |
|
|
||||||
|
|
||||||
**Цвет charter'а кодирует модель, а не роль прохода.** Это единственное
|
**Цвет charter'а кодирует модель, а не роль прохода.** Это единственное
|
||||||
назначение цвета: список агентов читается взглядом, и по нему сразу видно, чем
|
назначение цвета: список агентов читается взглядом, и по нему сразу видно, чем
|
||||||
@@ -116,15 +115,16 @@ description: "Конвейер ревью изменения — детерми
|
|||||||
здесь и **проверяется механически** — цвет ставится один раз при заведении
|
здесь и **проверяется механически** — цвет ставится один раз при заведении
|
||||||
charter'а, а модель потом двигает калибровка, и разъезжаются они молча.
|
charter'а, а модель потом двигает калибровка, и разъезжаются они молча.
|
||||||
|
|
||||||
**Самая дорогая модель — только двум проходам, и это калибровка, а не
|
**Моделей две, и верхняя из них — `opus`; выше неё конвейер не платит.** Замер:
|
||||||
осторожность.** Замер: на первом же прогоне конвейера самые ценные находки дали
|
на первом же прогоне самые ценные находки дали `opus`-проходы — сверка спек дала
|
||||||
`opus`-проходы — сверка спек дала 13 находок с оракулами, а проход про
|
13 находок с оракулами, а проход про идиоматичность (впоследствии упразднённый) —
|
||||||
идиоматичность (впоследствии упразднённый) — три эксперимента против драйвера БД
|
три эксперимента против драйвера БД с воспроизведёнными числами. Разницы в пользу
|
||||||
с воспроизведёнными числами. Разницы в пользу более дорогой модели на
|
модели **дороже** `opus` не обнаружилось ни на одном проходе, а прогон на ней
|
||||||
опиниативных проходах не обнаружилось — значит платить за неё там не за что.
|
стоил заметно дольше и дороже — значит платить за неё не за что.
|
||||||
|
|
||||||
Двое, у кого она остаётся, отобраны по одному признаку: **их ошибка
|
Двое из пяти держатся на `opus` по признаку, отдельному от суждения: **их ошибка
|
||||||
распространяется дальше собственной находки.**
|
распространяется дальше собственной находки.** Понижать их до `sonnet` вместе с
|
||||||
|
остальными дешёвыми проходами нельзя.
|
||||||
|
|
||||||
- `triage` — через него проходит всё, что оркестратор реализует **молча**:
|
- `triage` — через него проходит всё, что оркестратор реализует **молча**:
|
||||||
ложноположительная находка становится кодом, потерянный `critical` — дефектом.
|
ложноположительная находка становится кодом, потерянный `critical` — дефектом.
|
||||||
@@ -133,11 +133,6 @@ charter'а, а модель потом двигает калибровка, и
|
|||||||
потолок в 3 находки делает его дешёвым по выходу, а находка на предложении
|
потолок в 3 находки делает его дешёвым по выходу, а находка на предложении
|
||||||
стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо.
|
стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо.
|
||||||
|
|
||||||
`reimpl` намеренно **не** в этом списке, хотя он самый ценный из generative: его
|
|
||||||
стоимость определяется объёмом вывода (он пишет реализацию целиком), так что
|
|
||||||
дорогая модель множит самый большой счёт. Ценность же его — в **независимости**
|
|
||||||
взгляда, а не в мощности модели.
|
|
||||||
|
|
||||||
**Самая дешёвая модель не используется ни на одном проходе, и это не экономия
|
**Самая дешёвая модель не используется ни на одном проходе, и это не экономия
|
||||||
наоборот.** Дешёвая модель на опиниативном проходе даёт правдоподобные находки,
|
наоборот.** Дешёвая модель на опиниативном проходе даёт правдоподобные находки,
|
||||||
которые триаж обязан опровергать оракулом, — а это самая дорогая операция
|
которые триаж обязан опровергать оракулом, — а это самая дорогая операция
|
||||||
@@ -146,27 +141,25 @@ charter'а, а модель потом двигает калибровка, и
|
|||||||
Дешёвому проходу просто не осталось работы.
|
Дешёвому проходу просто не осталось работы.
|
||||||
|
|
||||||
Экономия достигается не понижением модели, а **непуском прохода**: `quick` —
|
Экономия достигается не понижением модели, а **непуском прохода**: `quick` —
|
||||||
четыре прохода, `deep` — восемь. Правило выбора профиля и есть главный
|
четыре прохода, `wide` — семь. Правило выбора профиля и есть главный
|
||||||
рычаг стоимости, и ступеней у него четыре именно поэтому.
|
рычаг стоимости, и ступеней у него три именно поэтому.
|
||||||
|
|
||||||
## Профили
|
## Профили
|
||||||
|
|
||||||
| Профиль | Когда | Стадии | Проходов |
|
| Профиль | Когда | Стадии | Проходов |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 |
|
| `quick` | багфикс, локальная правка, доки | 0, 1, 4 | 4 |
|
||||||
| `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 5 | 6 |
|
| `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 4 | 6 |
|
||||||
| `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 4, 5 | 7 |
|
| `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 3, 4 | 7 |
|
||||||
| `deep` | изменение вводит новое правило идентичности, слияния или разбора | 0, 1, 2, 3, 4, 5 | 8 |
|
|
||||||
| `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 1–3 |
|
| `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 1–3 |
|
||||||
|
|
||||||
**`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его
|
**`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его
|
||||||
отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов,
|
отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов,
|
||||||
граф зависимостей и инвентарь понятий вместо одного диффа. Ступень заведена
|
граф зависимостей и инвентарь понятий вместо одного диффа. Это и **верхняя
|
||||||
потому, что прыжок `standard` → `deep` стоил самого дорогого прохода конвейера, и
|
ступень**: выше неё конвейер не поднимается, и добавить к семи проходам ему
|
||||||
платить эту цену приходилось за одну архитектурную находку: изменений, которые
|
нечего.
|
||||||
трогают публичный контракт, но не вводят нового правила слияния, — большинство.
|
|
||||||
|
|
||||||
**Состав сверяется по этой таблице до коммита.** Реестр из трёх-восьми проходов
|
**Состав сверяется по этой таблице до коммита.** Реестр из трёх-семи проходов
|
||||||
проверяется взглядом — и это единственная защита от промаха, который уже
|
проверяется взглядом — и это единственная защита от промаха, который уже
|
||||||
случился: пропуск прохода **не отличим от прохода без находок** (гейт зелёный,
|
случился: пропуск прохода **не отличим от прохода без находок** (гейт зелёный,
|
||||||
спеки сошлись, отчёт выглядит полным), а заметить его мог бы только триаж,
|
спеки сошлись, отчёт выглядит полным), а заметить его мог бы только триаж,
|
||||||
@@ -177,9 +170,7 @@ charter'а, а модель потом двигает калибровка, и
|
|||||||
|
|
||||||
Правило выбора профиля — **по факту изменения, не по ощущению важности**:
|
Правило выбора профиля — **по факту изменения, не по ощущению важности**:
|
||||||
|
|
||||||
- вводится или меняется по существу правило, определяющее **идентичность, слияние
|
- изменение вводит **новое понятие или структурную единицу**: новый пакет
|
||||||
или разбор** данных (тест — ниже) → `deep`;
|
|
||||||
- иначе изменение вводит **новое понятие или структурную единицу**: новый пакет
|
|
||||||
или слой, новая точка входа, второй способ делать то, что уже делается, перенос
|
или слой, новая точка входа, второй способ делать то, что уже делается, перенос
|
||||||
ответственности между узлами → `wide`;
|
ответственности между узлами → `wide`;
|
||||||
- иначе меняется поведение, видимое снаружи, трогается схема, публичный контракт
|
- иначе меняется поведение, видимое снаружи, трогается схема, публичный контракт
|
||||||
@@ -203,74 +194,11 @@ charter'а, а модель потом двигает калибровка, и
|
|||||||
изменился, а от того, что появилось новое понятие: добавленное поле в
|
изменился, а от того, что появилось новое понятие: добавленное поле в
|
||||||
существующем ответе — не концепт.
|
существующем ответе — не концепт.
|
||||||
|
|
||||||
**Верхняя ступень и есть триггер независимой реализации** — раньше он был
|
Что здесь считается новым понятием, проект может уточнить в `docs/review.md`,
|
||||||
условием *внутри* `deep`, и профиль от этого распадался на два разных прогона под
|
разделе настройки конвейера. Это **уточнение**, а не отмена: не записано —
|
||||||
одним именем. Условие никуда не делось, оно просто переехало туда, где выбирается
|
работает список выше. Проект, где изменение контракта и правда архитектурное
|
||||||
профиль: изменение с новым правилом слияния — единственный случай, когда триаж
|
(публичный SDK, чужие потребители), там же поднимает его до `wide` — и это
|
||||||
называл отсутствие `reimpl` дырой покрытия.
|
уточнение, а не возврат прежнего умолчания.
|
||||||
|
|
||||||
Что здесь считается новым понятием и что — правилом идентичности, проект может
|
|
||||||
уточнить в `docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не
|
|
||||||
отмена: не записано — работает список выше. Проект, где изменение контракта и
|
|
||||||
правда архитектурное (публичный SDK, чужие потребители), там же поднимает его до
|
|
||||||
`wide` — и это уточнение, а не возврат прежнего умолчания.
|
|
||||||
|
|
||||||
### Идентичность, слияние, разбор — тест, а не список
|
|
||||||
|
|
||||||
Три слова названы затем, чтобы верхнюю ступень нельзя было выбрать по ощущению.
|
|
||||||
Читаются они **тестом**, применимым к любому проекту на любом языке; домен, стек
|
|
||||||
и имена узлов в тест не входят.
|
|
||||||
|
|
||||||
Правило принадлежит этому классу, если сходятся **три условия**:
|
|
||||||
|
|
||||||
1. **вариантов несколько** — два добросовестных исполнителя выберут разное, и оба
|
|
||||||
решения защитимы;
|
|
||||||
2. **спека между ними не выбирает** — она требует, чтобы вещи сравнивались,
|
|
||||||
сливались или разбирались, но не называет исход в пограничном случае;
|
|
||||||
3. **неверный выбор не падает** — он даёт правдоподобный результат и меняет смысл
|
|
||||||
данных молча.
|
|
||||||
|
|
||||||
**Отрицательный тест, и он важнее трёх положительных:** если неверная реализация
|
|
||||||
красит гейт, роняет запрос или ломает тест — это **не** сюда. Такое ловят проходы
|
|
||||||
дешевле, и платить за него верхней ступенью не за что.
|
|
||||||
|
|
||||||
Отсюда же и причина, по которой класс достался самому дорогому проходу:
|
|
||||||
независимая реализация **выберет другой вариант**, и дифф между двумя вариантами
|
|
||||||
и есть находка. Там, где вариант один, она совпадёт с существующей — и верхняя
|
|
||||||
ступень оплатит подтверждение того, что и так известно.
|
|
||||||
|
|
||||||
Три слова — это **три места**, где такие правила водятся, и все три стоят на
|
|
||||||
границе, где данные входят или встречаются:
|
|
||||||
|
|
||||||
| Слово | Вопрос, на который правило отвечает | Что в нём выбирается |
|
|
||||||
|---|---|---|
|
|
||||||
| **идентичность** | когда две вещи считаются одной и той же | состав ключа и что в него намеренно не входит; нормализация перед сравнением — регистр, пробелы, кодировка, время, единицы, округление; дедупликация |
|
|
||||||
| **слияние** | что получается, когда два представления одного встретились | кто побеждает при конфликте; накопительное против замещающего; что делать с отсутствующим полем; тай-брейк при равенстве |
|
|
||||||
| **разбор** | как внешнее представление становится внутренним | границы токенов; извлечение полей; сопоставление с известным набором; поведение на неоднозначном входе |
|
|
||||||
|
|
||||||
**Триггер — новое или изменённое правило, а не код рядом с ним.** Правка
|
|
||||||
сообщения об ошибке в узле, который разбирает вход, ступень не поднимает.
|
|
||||||
Поднимают: заводится ключ или меняется его состав; в слияние добавляется источник
|
|
||||||
или меняется победитель при конфликте; у разбора появляется новый вид входа или
|
|
||||||
новая ветка неоднозначности. Без этой оговорки проект, чей домен и **состоит** из
|
|
||||||
таких правил, оказывался бы в `deep` всегда — та же болезнь, от которой лечилась
|
|
||||||
ступень `wide`.
|
|
||||||
|
|
||||||
**Ступень определяет класс правила, а не вид работы.** Миграция схемы сама по
|
|
||||||
себе `standard` — но миграция, которая **переносит данные** по правилу («сложить
|
|
||||||
дубли», «привести к одному виду перед сравнением»), несёт правило идентичности и
|
|
||||||
потому `deep`. Одно и то же слово в описании задачи попадает в разные ступени, и
|
|
||||||
это не противоречие: смотрят не на слово, а на то, есть ли выбор, которого спека
|
|
||||||
не сделала.
|
|
||||||
|
|
||||||
**Проект, у которого таких правил нет вовсе, `deep` не запускает никогда.** Это
|
|
||||||
законное состояние, а не признак недонастройки: бывают проекты, где данные
|
|
||||||
приходят уже нормализованными, ничего ни с чем не сливается, а внешних форматов
|
|
||||||
нет. Верхняя ступень там просто не срабатывает, и придумывать ей повод не надо.
|
|
||||||
|
|
||||||
Свои места проект перечисляет в `docs/review.md`, подраздел «Триггеры профиля» —
|
|
||||||
поимённо, узлами или capability. Перечень **производен от теста**: он не расширяет
|
|
||||||
класс, а называет, где этот класс живёт именно здесь.
|
|
||||||
|
|
||||||
### Профиль — максимум по поверхности, и отсюда размер задачи
|
### Профиль — максимум по поверхности, и отсюда размер задачи
|
||||||
|
|
||||||
@@ -298,18 +226,17 @@ charter'а, а модель потом двигает калибровка, и
|
|||||||
|
|
||||||
Профиль отвечает «какие проходы», порядок — «что кого ждёт». Стадии остаются
|
Профиль отвечает «какие проходы», порядок — «что кого ждёт». Стадии остаются
|
||||||
единицей **состава** (профиль набирается стадиями, см. таблицу выше), но порядок
|
единицей **состава** (профиль набирается стадиями, см. таблицу выше), но порядок
|
||||||
задают **не их номера**: между стадиями 1–4 настоящих зависимостей нет — ни один
|
задают **не их номера**: между стадиями 1–3 настоящих зависимостей нет — ни один
|
||||||
проход не читает вывод другого, — и очередь между ними была бы платой ни за что.
|
проход не читает вывод другого, — и очередь между ними была бы платой ни за что.
|
||||||
|
|
||||||
Рёбер три вида, и они разной природы. Путать их нельзя: первое про
|
Рёбер два вида, и они разной природы. Путать их нельзя: первое про
|
||||||
**осмысленность** (на красном гейте опиниативный проход не о чем), второе про
|
**осмысленность** (на красном гейте опиниативный проход не о чем), второе про
|
||||||
**железо**, третье про **деньги**.
|
**железо**.
|
||||||
|
|
||||||
| Ребро | Смысл | Между кем |
|
| Ребро | Смысл | Между кем |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | гейт → все опиниативные; все проходы → триаж |
|
| **зависимость** | B не стартует, пока A не закончил, потому что без A задание B не определено | гейт → все опиниативные; все проходы → триаж |
|
||||||
| **конфликт за ресурс** | A и B не держат машину одновременно; кто из них первый — неважно, направления у ребра нет | проходы, помеченные «держит машину» |
|
| **конфликт за ресурс** | A и B не держат машину одновременно; кто из них первый — неважно, направления у ребра нет | проходы, помеченные «держит машину» |
|
||||||
| **барьер стоимости** | дорогое не запускается, пока дешёвое не сказало, что форма изменения выживет | только `deep` |
|
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
@@ -318,24 +245,19 @@ flowchart TD
|
|||||||
code["code"]
|
code["code"]
|
||||||
adversary["adversary<br/>(держит машину)"]
|
adversary["adversary<br/>(держит машину)"]
|
||||||
ops["ops<br/>(держит машину)"]
|
ops["ops<br/>(держит машину)"]
|
||||||
architecture["architecture<br/>(wide, deep)"]
|
architecture["architecture<br/>(wide)"]
|
||||||
barrier{{"форма изменения выживает?"}}
|
|
||||||
reimpl["reimpl"]
|
|
||||||
triage["triage — единственный сток"]
|
triage["triage — единственный сток"]
|
||||||
|
|
||||||
gate -->|зелёный| specs
|
gate -->|зелёный| specs
|
||||||
gate -->|зелёный| code
|
gate -->|зелёный| code
|
||||||
gate -->|зелёный| adversary
|
gate -->|зелёный| adversary
|
||||||
gate -->|зелёный| ops
|
gate -->|зелёный| ops
|
||||||
gate -->|"зелёный, wide и deep"| architecture
|
gate -->|"зелёный, wide"| architecture
|
||||||
adversary -. один ресурс — машина .- ops
|
adversary -. один ресурс — машина .- ops
|
||||||
specs --> barrier
|
specs --> triage
|
||||||
code --> barrier
|
code --> triage
|
||||||
adversary --> barrier
|
adversary --> triage
|
||||||
ops --> barrier
|
ops --> triage
|
||||||
barrier -->|"deep"| reimpl
|
|
||||||
barrier -->|"quick, standard, wide: барьера нет"| triage
|
|
||||||
reimpl --> triage
|
|
||||||
architecture --> triage
|
architecture --> triage
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -370,7 +292,7 @@ flowchart TD
|
|||||||
| `adversary` | да | находка есть **построенный путь**: он пишет падающий тест и гоняет его |
|
| `adversary` | да | находка есть **построенный путь**: он пишет падающий тест и гоняет его |
|
||||||
| `ops` | да | доказывает числами: время удержания блокировки, пик кучи, темп роста журнала |
|
| `ops` | да | доказывает числами: время удержания блокировки, пик кучи, темп роста журнала |
|
||||||
| `triage` | да | проверяет оракул `critical`/`major` запуском — но он сток и тоже один |
|
| `triage` | да | проверяет оракул `critical`/`major` запуском — но он сток и тоже один |
|
||||||
| `specs`, `code`, `reimpl`, `architecture`, `rubric` | нет | читают и рассуждают; `reimpl` пишет свою реализацию в черновик, но не исполняет её |
|
| `specs`, `code`, `architecture`, `rubric` | нет | читают и рассуждают, ничего не исполняют |
|
||||||
|
|
||||||
**Правило про ресурс, а не про имена.** Раньше здесь стояло именованное
|
**Правило про ресурс, а не про имена.** Раньше здесь стояло именованное
|
||||||
исключение «`adversary` и `ops`»; оно рассыпается, как только проход начнёт
|
исключение «`adversary` и `ops`»; оно рассыпается, как только проход начнёт
|
||||||
@@ -385,39 +307,26 @@ flowchart TD
|
|||||||
Проект вправе пометить «держит машину» и другой проход — в `docs/review.md`,
|
Проект вправе пометить «держит машину» и другой проход — в `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-проходов,
|
Recall обоих равен длине их источника — это и есть предел applicative-проходов,
|
||||||
ради которого существует стадия 2.
|
ради которого существует стадия 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`)
|
||||||
|
|
||||||
Единственный проход, ради которого существует **барьер стоимости**, и
|
Агент `review-architecture`. Уходит в первой волне, сразу после зелёного гейта, в
|
||||||
единственное, что отличает `deep` от `wide`.
|
одном ряду со стадиями 1 и 2. Машину не держит, ждать ему нечего.
|
||||||
|
|
||||||
- `review-reimpl` — пишет свою реализацию, не открывая существующую, затем
|
|
||||||
диффит по решениям. **Профиль и есть его условие:** `deep` выбирается ровно
|
|
||||||
тогда, когда вводится или меняется по существу правило идентичности, слияния
|
|
||||||
или разбора — по тесту из раздела «Идентичность, слияние, разбор»; проектный
|
|
||||||
перечень мест, где такие правила живут, — в `docs/review.md`, если записан. Это
|
|
||||||
самый дорогой проход конвейера (его счёт определяется объёмом вывода — он пишет
|
|
||||||
реализацию целиком), а вне этого случая независимый взгляд в значительной мере
|
|
||||||
уже дал профиль `design`: код писался под его находки. Условие выбрано по факту:
|
|
||||||
единственный раз, когда триаж назвал отсутствие `reimpl` дырой покрытия, — это
|
|
||||||
была задача с новым правилом слияния сущностей.
|
|
||||||
|
|
||||||
Такие правила обычно занимают десятки строк, но определяют смысл **всех** данных
|
|
||||||
проекта. Отсюда особенность верхней ступени, из-за которой её легко выбрать
|
|
||||||
неверно: самый дорогой проход тратится на самый **маленький** дифф. `deep` не про
|
|
||||||
размер изменения и не про его опасность — он про класс правила.
|
|
||||||
|
|
||||||
Раньше это условие стояло **внутри** профиля, и `deep` означал то семь проходов,
|
|
||||||
то восемь. Реестр состава, который «проверяется взглядом», проверять было нечем:
|
|
||||||
у профиля не было одного правильного ответа. Теперь ступеней две — `wide` и
|
|
||||||
`deep`, — и у каждой состав ровно один.
|
|
||||||
|
|
||||||
## Стадия 4 — Global (`wide`, `deep`, `design`)
|
|
||||||
|
|
||||||
Агент `review-architecture`. В `deep` стоит **за барьером стоимости** (ждать ему
|
|
||||||
там всё равно нечего), в `wide` и `design` — в первой волне, сразу после старта
|
|
||||||
профиля. Машину не держит, с `reimpl` конфликта не имеет: за барьером они уходят
|
|
||||||
разом.
|
|
||||||
|
|
||||||
**Условие этой стадии и есть условие ступени `wide`:** изменение вводит новое
|
**Условие этой стадии и есть условие ступени `wide`:** изменение вводит новое
|
||||||
понятие или структурную единицу. Не «изменение крупное» и не «изменение опасное»:
|
понятие или структурную единицу. Не «изменение крупное» и не «изменение опасное»:
|
||||||
@@ -562,7 +443,7 @@ Recall обоих равен длине их источника — это и е
|
|||||||
конфигурируемость, подстраховка поверх подстраховки. Потолок — 3 находки плюс
|
конфигурируемость, подстраховка поверх подстраховки. Потолок — 3 находки плюс
|
||||||
секция «дешевле переделать до мерджа».
|
секция «дешевле переделать до мерджа».
|
||||||
|
|
||||||
## Стадия 5 — Triage (обязательна)
|
## Стадия 4 — Triage (обязательна)
|
||||||
|
|
||||||
Агент `review-triage`. **Единственный сток графа и единственный, кто агрегирует.**
|
Агент `review-triage`. **Единственный сток графа и единственный, кто агрегирует.**
|
||||||
Входящие рёбра — все запущенные проходы: пока хоть один не вернул отчёт, триаж не
|
Входящие рёбра — все запущенные проходы: пока хоть один не вернул отчёт, триаж не
|
||||||
@@ -570,8 +451,8 @@ Recall обоих равен длине их источника — это и е
|
|||||||
**список запущенных проходов**; возвращает финальный отчёт.
|
**список запущенных проходов**; возвращает финальный отчёт.
|
||||||
|
|
||||||
Отсюда же правило, которое иначе выглядит придиркой: **триаж на неполном графе не
|
Отсюда же правило, которое иначе выглядит придиркой: **триаж на неполном графе не
|
||||||
запускается**. Прогон, остановленный барьером или ранним выходом, до стока не
|
запускается**. Прогон, остановленный на полпути находкой «переделать форму», до
|
||||||
доезжает — его отчёт агрегировал бы половину и выглядел бы полным.
|
стока не доезжает — его отчёт агрегировал бы половину и выглядел бы полным.
|
||||||
|
|
||||||
Без триажа проходы дают порядка сорока замечаний при единицах существенных.
|
Без триажа проходы дают порядка сорока замечаний при единицах существенных.
|
||||||
Потребитель здесь — оркестратор, который **молча реализует** всё, что прочитал:
|
Потребитель здесь — оркестратор, который **молча реализует** всё, что прочитал:
|
||||||
@@ -608,7 +489,7 @@ Recall обоих равен длине их источника — это и е
|
|||||||
мелкой нарезке это самая большая статья конвейера. Рубрика же на узел, который не
|
мелкой нарезке это самая большая статья конвейера. Рубрика же на узел, который не
|
||||||
вводит нового понятия, порождает свойства уже существующего рода — те, что и так
|
вводит нового понятия, порождает свойства уже существующего рода — те, что и так
|
||||||
записаны конвенциями и спеками; а `architecture` без нового понятия отвечает «нет»
|
записаны конвенциями и спеками; а `architecture` без нового понятия отвечает «нет»
|
||||||
на свой главный вопрос ещё до запуска (см. «Стадия 4»).
|
на свой главный вопрос ещё до запуска (см. «Стадия 3»).
|
||||||
|
|
||||||
**Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
**Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
||||||
нечего; машину не держит ни один проход; сток — не триаж, а шаг 5 пайплайна
|
нечего; машину не держит ни один проход; сток — не триаж, а шаг 5 пайплайна
|
||||||
@@ -712,6 +593,20 @@ flowchart TD
|
|||||||
никто. Класс обратимый — портит форму кода, не данные, — и его надо признавать в
|
никто. Класс обратимый — портит форму кода, не данные, — и его надо признавать в
|
||||||
границах покрытия, а не считать проверенным.
|
границах покрытия, а не считать проверенным.
|
||||||
|
|
||||||
|
Так же честно и про второй упразднённый проход: **«не знаю, чего не знаю» больше
|
||||||
|
не достаёт никто.** Проход независимой реализации писал свою версию узла, не
|
||||||
|
открывая существующую, и диффил по решениям — декомпозиция, владение данными,
|
||||||
|
модель конкурентности, форма решения там, где спека выбора не сделала. Он снят по
|
||||||
|
решению оператора о **стоимости** — счёт определялся объёмом вывода, и на прогон
|
||||||
|
он тратил больше всех остальных проходов вместе, — а не по замеру, который
|
||||||
|
[calibration.md](references/calibration.md) требует перед удалением. Значит и
|
||||||
|
записывается это как сознательное сужение, а не как «класс оказался пустым»:
|
||||||
|
остаток независимого взгляда даёт профиль `design` (код пишется под его находки) и
|
||||||
|
`architecture` (второй способ, лишние слои), но **альтернативной реализации, с
|
||||||
|
которой можно сдиффить решения, у конвейера теперь нет**. Класс идёт строкой в
|
||||||
|
границы покрытия каждого прогона — там же, где проект перечисляет своё в
|
||||||
|
подразделе «перестали проверять сознательно».
|
||||||
|
|
||||||
Это и есть причина, по которой конвейер готовит ревью, а не заменяет его.
|
Это и есть причина, по которой конвейер готовит ревью, а не заменяет его.
|
||||||
|
|
||||||
## Ссылки
|
## Ссылки
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ stateDiagram-v2
|
|||||||
| `review-specs` | поведение вне спеки | добавить незаказанный фолбэк-дефолт на пустом входе |
|
| `review-specs` | поведение вне спеки | добавить незаказанный фолбэк-дефолт на пустом входе |
|
||||||
| `review-code` | нарушение прозаической конвенции | увести штатный отказ мимо единой точки трансляции ошибки |
|
| `review-code` | нарушение прозаической конвенции | увести штатный отказ мимо единой точки трансляции ошибки |
|
||||||
| `review-rubric` | нарушенное свойство узла | у клиента внешнего сервиса убрать таймаут и протяжку `context` |
|
| `review-rubric` | нарушенное свойство узла | у клиента внешнего сервиса убрать таймаут и протяжку `context` |
|
||||||
| `review-reimpl` | форма решения | размазать решение по трём слоям там, где хватало одной функции |
|
|
||||||
| `review-architecture` | второй способ | завести вторую точку генерации id мимо единой |
|
| `review-architecture` | второй способ | завести вторую точку генерации id мимо единой |
|
||||||
| `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище |
|
| `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище |
|
||||||
| `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле |
|
| `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле |
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
- **`critical` по основанию «нарушен инвариант проекта» требует инвариантов.**
|
- **`critical` по основанию «нарушен инвариант проекта» требует инвариантов.**
|
||||||
Ссылка идёт на пункт раздела инвариантов `CLAUDE.md` дословно. Без них основание
|
Ссылка идёт на пункт раздела инвариантов `CLAUDE.md` дословно. Без них основание
|
||||||
недоступно — см. [project-facts.md](project-facts.md), поразрядная деградация.
|
недоступно — см. [project-facts.md](project-facts.md), поразрядная деградация.
|
||||||
- **Расхождение — не дефект, пока не названо последствие.** Особенно для прохода
|
- **Расхождение — не дефект, пока не названо последствие.** Особенно для
|
||||||
независимой реализации: «я бы сделал иначе» без последствия не выводится.
|
архитектурного прохода: «я бы сделал иначе» без последствия не выводится.
|
||||||
|
|
||||||
## Шкала severity
|
## Шкала severity
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
«запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась
|
«запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась
|
||||||
5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом
|
5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом
|
||||||
занятости. Числа в `docs/research/`, настройки в `docs/database.md`, и оба
|
занятости. Числа в `docs/research/`, настройки в `docs/database.md`, и оба
|
||||||
читает `ops`, `adversary`, `reimpl`.
|
читает `ops` и `adversary`.
|
||||||
- **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там
|
- **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там
|
||||||
нет — она **выводится по обратимости последствия** и помечается «выведена по
|
нет — она **выводится по обратимости последствия** и помечается «выведена по
|
||||||
обратимости», а не выдаётся за решение проекта.
|
обратимости», а не выдаётся за решение проекта.
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `CLAUDE.md` без инвариантов | `critical` по основанию «нарушен инвариант проекта» не присваивается никем |
|
| `CLAUDE.md` без инвариантов | `critical` по основанию «нарушен инвариант проекта» не присваивается никем |
|
||||||
| `docs/security.md` | `adversary` не знает периметра — формулирует условиями, `critical` не ставит |
|
| `docs/security.md` | `adversary` не знает периметра — формулирует условиями, `critical` не ставит |
|
||||||
| `docs/research/` | числа неизвестны `specs`, `ops`, `adversary`, `reimpl` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» |
|
| `docs/research/` | числа неизвестны `specs`, `ops`, `adversary` — формулируют условиями, а `specs` теряет проверку «требование против наблюдения» |
|
||||||
| `docs/database.md` | замер не с чем сравнить: находка не поднимается выше гипотезы |
|
| `docs/database.md` | замер не с чем сравнить: находка не поднимается выше гипотезы |
|
||||||
| `docs/passport.md` | `architecture` теряет границу домена и вырождается в общее мнение |
|
| `docs/passport.md` | `architecture` теряет границу домена и вырождается в общее мнение |
|
||||||
| `docs/review.md` | `triage` отсеивает вслепую: типовых ложноположительных нет |
|
| `docs/review.md` | `triage` отсеивает вслепую: типовых ложноположительных нет |
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ description: Проводит несколько задач разом — пл
|
|||||||
где уже мерили или уже ломалось.
|
где уже мерили или уже ломалось.
|
||||||
|
|
||||||
Ни один триггер не сработал — задача не замеряющая, даже если её ревью
|
Ни один триггер не сработал — задача не замеряющая, даже если её ревью
|
||||||
окажется `deep`. Профиль про глубину проверки, замеряющая — про соревнование за
|
окажется `wide`. Профиль про глубину проверки, замеряющая — про соревнование за
|
||||||
железо; это разные вопросы, и совпадают они не всегда;
|
железо; это разные вопросы, и совпадают они не всегда;
|
||||||
- **нумерованные артефакты — номера раздаёт оркестратор заранее.** Если проект
|
- **нумерованные артефакты — номера раздаёт оркестратор заранее.** Если проект
|
||||||
нумерует миграции (путь — `docs/.pm.json`, ключ `migrations`), посмотри последний
|
нумерует миграции (путь — `docs/.pm.json`, ключ `migrations`), посмотри последний
|
||||||
@@ -241,8 +241,8 @@ flowchart TD
|
|||||||
а не сабагент: батч идёт по одной задаче → режим умолчательный, **`по
|
а не сабагент: батч идёт по одной задаче → режим умолчательный, **`по
|
||||||
графу`** (машина свободна); батч идёт волнами → **`линейно`**, твой worktree
|
графу`** (машина свободна); батч идёт волнами → **`линейно`**, твой worktree
|
||||||
не один на машине, и этой причиной ты обязан объяснить режим в отчёте.
|
не один на машине, и этой причиной ты обязан объяснить режим в отчёте.
|
||||||
Внутренние рёбра графа — цепочку проходов, держащих машину, и барьер
|
Внутренние рёбра графа — цепочку проходов, держащих машину — конвейер
|
||||||
стоимости — конвейер соблюдает сам, в любом режиме;
|
соблюдает сам, в любом режиме;
|
||||||
- **если вложенные сабагенты недоступны** (движок не даёт запускать агентов из
|
- **если вложенные сабагенты недоступны** (движок не даёт запускать агентов из
|
||||||
агента) — не пропускай ревью и не понижай профиль: проведи его **инлайн** по
|
агента) — не пропускай ревью и не понижай профиль: проведи его **инлайн** по
|
||||||
тем же charter'ам `av-dev-pipeline`, сохранив обязательное — гейт до
|
тем же charter'ам `av-dev-pipeline`, сохранив обязательное — гейт до
|
||||||
|
|||||||
@@ -270,8 +270,7 @@ flowchart TD
|
|||||||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||||||
знает свои рёбра: гейт открывает опиниативные проходы, проходы с пометкой «держит
|
знает свои рёбра: гейт открывает опиниативные проходы, проходы с пометкой «держит
|
||||||
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
||||||
доказанной), дорогие generative-проходы ждут барьера стоимости, триаж — сток.
|
доказанной), триаж — сток. Твоего участия это не требует.
|
||||||
Твоего участия это не требует.
|
|
||||||
|
|
||||||
Просить **`линейно`** нужно только по причине, и она называется строкой: так
|
Просить **`линейно`** нужно только по причине, и она называется строкой: так
|
||||||
сказал оператор; машина занята чем-то ещё (в том числе соседней задачей батча);
|
сказал оператор; машина занята чем-то ещё (в том числе соседней задачей батча);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
name: doc-code-drift
|
name: doc-code-drift
|
||||||
description: "Сверка документов канона с кодом по закрытому перечню проверяемых фактов: имя основной ветки и команды из CLAUDE.md, запреты с путями, testdata и временный каталог, путь миграций из .pm.json, внешние зависимости поимённо в architecture.md против манифеста, настройки с числовым значением в database.md против конфига и кода, единые точки проекта против реального числа реализаций, capability против существующих модулей. Отвечает на «этот факт ещё верен», а не «эта архитектура правильная». Читает весь репозиторий, гоняет только читающие команды. Отдаёт готовые формулировки и ничего не правит сам. Согласованность документов между собой смотрит агент doc-consistency. Использовать на сессии между спринтами, а также после приведения проекта к канону (adopt) и после повышения версии канона (upgrade). Только чтение."
|
description: "Сверка документов канона с кодом по закрытому перечню проверяемых фактов: имя основной ветки и команды из CLAUDE.md, запреты с путями, testdata и временный каталог, путь миграций из .pm.json, внешние зависимости поимённо в architecture.md против манифеста, настройки с числовым значением в database.md против конфига и кода, единые точки проекта против реального числа реализаций, capability против существующих модулей. Отвечает на «этот факт ещё верен», а не «эта архитектура правильная». Читает весь репозиторий, гоняет только читающие команды. Отдаёт готовые формулировки и ничего не правит сам. Согласованность документов между собой смотрит агент doc-consistency. Использовать на сессии между спринтами, а также после приведения проекта к канону (adopt) и после повышения версии канона (upgrade). Только чтение."
|
||||||
tools: Read, Grep, Glob, Bash
|
tools: Read, Grep, Glob, Bash
|
||||||
model: fable
|
model: opus
|
||||||
color: red
|
color: yellow
|
||||||
---
|
---
|
||||||
|
|
||||||
Ты — **сверка документов канона с кодом**. Один вопрос: **этот факт ещё верен?**
|
Ты — **сверка документов канона с кодом**. Один вопрос: **этот факт ещё верен?**
|
||||||
|
|||||||
@@ -106,12 +106,12 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
| Документ | Вопрос | Кто читает, кроме человека |
|
| Документ | Вопрос | Кто читает, кроме человека |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `CLAUDE.md` | что нельзя нарушать, чем краснеет гейт | все агенты, всегда |
|
| `CLAUDE.md` | что нельзя нарушать, чем краснеет гейт | все агенты, всегда |
|
||||||
| `passport.md` | зачем и для кого, чем это **не** является | `architecture`, `rubric`, `reimpl`, `specs` |
|
| `passport.md` | зачем и для кого, чем это **не** является | `architecture`, `rubric`, `specs` |
|
||||||
| `architecture.md` | как сложено и где что работает | все проходы ревью |
|
| `architecture.md` | как сложено и где что работает | все проходы ревью |
|
||||||
| `database.md` | что лежит в хранилище и какими настройками | `ops`, `adversary`, `reimpl` |
|
| `database.md` | что лежит в хранилище и какими настройками | `ops`, `adversary` |
|
||||||
| `security.md` | против кого защищаемся и что вне модели | `adversary` |
|
| `security.md` | против кого защищаемся и что вне модели | `adversary` |
|
||||||
| `conventions/` | как мы пишем код | `code` |
|
| `conventions/` | как мы пишем код | `code` |
|
||||||
| `research/` | что показала реальность, а не документация | `specs`, `reimpl`, `ops`, `adversary` |
|
| `research/` | что показала реальность, а не документация | `specs`, `ops`, `adversary` |
|
||||||
| `adr/` | почему решено именно так | `architecture` |
|
| `adr/` | почему решено именно так | `architecture` |
|
||||||
| `review.md` | как настроен конвейер и что уже проскакивало | `triage`, каждый проход — свою часть |
|
| `review.md` | как настроен конвейер и что уже проскакивало | `triage`, каждый проход — свою часть |
|
||||||
| `openspec/specs/` | что система делает — нормативно | `specs` |
|
| `openspec/specs/` | что система делает — нормативно | `specs` |
|
||||||
@@ -232,12 +232,11 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
- **Вопросы к проходам** — поимённо, в форме `<имя прохода>: <вопрос>
|
- **Вопросы к проходам** — поимённо, в форме `<имя прохода>: <вопрос>
|
||||||
(<провенанс>)`;
|
(<провенанс>)`;
|
||||||
- **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью:
|
- **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью:
|
||||||
что в этом проекте считается **новым понятием или структурной единицей** (это
|
что в этом проекте считается **новым понятием или структурной единицей** — это
|
||||||
поднимает прогон до `wide`) и **где живут правила идентичности, слияния и
|
поднимает прогон до `wide`, верхней ступени. Перечнем мест, а не вторым
|
||||||
разбора** (до `deep`) — перечнем мест, производным от теста конвейера, а не
|
определением класса. Уточняет умолчания, а не отменяет их. Рабочее умолчание —
|
||||||
вторым определением класса. Уточняет умолчания, а не отменяет их. Рабочее
|
`standard`: миграция схемы и публичный контракт ступень **не** поднимают, их
|
||||||
умолчание — `standard`: миграция схемы и публичный контракт ступень **не**
|
проверяют проходы, которые в `standard` и так есть;
|
||||||
поднимают, их проверяют проходы, которые в `standard` и так есть;
|
|
||||||
- **Недоступно проверке** — два подраздела: «не проверит ни один проход»
|
- **Недоступно проверке** — два подраздела: «не проверит ни один проход»
|
||||||
(принципиальная граница, по факту промаха не пересматривается) и «перестали
|
(принципиальная граница, по факту промаха не пересматривается) и «перестали
|
||||||
проверять сознательно» (пересматривается первым).
|
проверять сознательно» (пересматривается первым).
|
||||||
|
|||||||
@@ -127,13 +127,20 @@ upgrade` идёт по записям снизу вверх от версии п
|
|||||||
человека. **Переименование ADR это перенос ссылок**: слаг стоит в
|
человека. **Переименование ADR это перенос ссылок**: слаг стоит в
|
||||||
`adr/README.md`, в `architecture.md` и в чужих документах, и делается одним
|
`adr/README.md`, в `architecture.md` и в чужих документах, и делается одним
|
||||||
проходом, иначе останутся битые ссылки (их `docs.py` потом и покажет).
|
проходом, иначе останутся битые ссылки (их `docs.py` потом и покажет).
|
||||||
8. `docs/.pm.json`: `"canon": 4`.
|
8. `docs/review.md`, подраздел «Триггеры профиля»: снести перечень мест для
|
||||||
9. Позвать **обоих судей** — `doc-consistency` и `doc-code-drift`, шагом 6
|
`deep` — профиль упразднён вместе с проходом независимой реализации, и
|
||||||
`upgrade`. Пунктов выше девять, половина из них ручная, и именно здесь видно,
|
перечень стал указателем в пустоту. Перечень для `wide` (новое понятие или
|
||||||
какие сделаны только наполовину: переименования секций и полей разводят
|
структурная единица) остаётся: он и поднимает прогон до верхней ступени. Там
|
||||||
документы, а `check` сверяет число версии, а не существо. Первый прогон на
|
же проверить журнал дефектов и «Недоступно проверке» на упоминания
|
||||||
живом проекте вдобавок самый урожайный — правило единственного дома до сих пор
|
независимой реализации: класс «форма решения, где спека выбора не сделала»
|
||||||
никто не проверял. Разбирать порциями, а не одним заходом.
|
переезжает в подраздел «перестали проверять сознательно».
|
||||||
|
9. `docs/.pm.json`: `"canon": 4`.
|
||||||
|
10. Позвать **обоих судей** — `doc-consistency` и `doc-code-drift`, шагом 6
|
||||||
|
`upgrade`. Пунктов выше десять, половина из них ручная, и именно здесь видно,
|
||||||
|
какие сделаны только наполовину: переименования секций и полей разводят
|
||||||
|
документы, а `check` сверяет число версии, а не существо. Первый прогон на
|
||||||
|
живом проекте вдобавок самый урожайный — правило единственного дома до сих пор
|
||||||
|
никто не проверял. Разбирать порциями, а не одним заходом.
|
||||||
|
|
||||||
## Версия 3 — 2026-08-04
|
## Версия 3 — 2026-08-04
|
||||||
|
|
||||||
|
|||||||
@@ -284,19 +284,11 @@
|
|||||||
### Триггеры профиля
|
### Триггеры профиля
|
||||||
|
|
||||||
Проектная конкретизация правила выбора профиля: что здесь считается **новым
|
Проектная конкретизация правила выбора профиля: что здесь считается **новым
|
||||||
понятием или структурной единицей** (поднимает прогон до `wide` и запускает
|
понятием или структурной единицей** — это поднимает прогон до `wide`, верхней
|
||||||
архитектурный проход) и **где живут правила идентичности, слияния и разбора**
|
ступени, и запускает архитектурный проход. Перечнем узлов или capability,
|
||||||
(до `deep`, запускает независимую реализацию) — перечнем узлов или capability,
|
|
||||||
поимённо. Уточняет умолчания конвейера, не отменяет их; рабочее умолчание —
|
поимённо. Уточняет умолчания конвейера, не отменяет их; рабочее умолчание —
|
||||||
`standard`.
|
`standard`.
|
||||||
|
|
||||||
Перечень для `deep` **производен от теста конвейера**, а не заменяет его:
|
|
||||||
правило попадает в класс, когда вариантов несколько, спека между ними не
|
|
||||||
выбирает, а неверный выбор не падает, а молча меняет смысл данных. Перечисляй
|
|
||||||
места, где этот класс здесь живёт, а не переписывай определение. Таких мест нет
|
|
||||||
вовсе — так и напиши: `deep` тогда не запускается никогда, и это законное
|
|
||||||
состояние.
|
|
||||||
|
|
||||||
### Недоступно проверке
|
### Недоступно проверке
|
||||||
|
|
||||||
**Не проверит ни один проход** — принципиальная граница; по факту промаха не
|
**Не проверит ни один проход** — принципиальная граница; по факту промаха не
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4
|
|||||||
|
|
||||||
# Дом раскладки — «Модель по проходу» в review-pipeline/SKILL.md; здесь её
|
# Дом раскладки — «Модель по проходу» в review-pipeline/SKILL.md; здесь её
|
||||||
# механизация. Порядок цветов — порядок стоимости прогона.
|
# механизация. Порядок цветов — порядок стоимости прогона.
|
||||||
PALETTE = {"sonnet": "green", "opus": "yellow", "fable": "red"}
|
PALETTE = {"sonnet": "green", "opus": "yellow"}
|
||||||
|
|
||||||
SKILL_KEYS = {"name", "description"}
|
SKILL_KEYS = {"name", "description"}
|
||||||
AGENT_KEYS = {"name", "description", "tools", "model", "color"}
|
AGENT_KEYS = {"name", "description", "tools", "model", "color"}
|
||||||
|
|||||||
Reference in New Issue
Block a user