классификация задачи: три категории документов и метка вместо ступени
Канон 5 объявил «каждый документ docs/ — тема ревью». Правило верно ровно наполовину и потому вредно целиком. Паспорт и схему хранилища ревью читает, но темами они не являются: по ним нельзя сказать «в этом изменении сделано не так», они задают границу, по которой судит чужая тема. Журнал решений и журнал наблюдений ревью изменения не нужны вовсе — ADR объясняет прошлое, а не предъявляет требование. Разметчик, применявший правило буквально, обязан был либо завести фантомные темы passport, adr, database, research и продублировать ими работу architecture и operations, либо потерять четыре документа молча; случались обе ветки, и в собственном образце плана docs/passport.md не попадал ни строкой, а обязательная арифметика покрытия при этом не сходилась. Категорий теперь три, разрез проверяемый. Тема — да, прямо: conventions, security, architecture и любой свой документ проекта. Источник темы — нет, но он задаёт границу для чужой: passport, database, CLAUDE.md, openspec/specs. Процессный — нет, он про то, как мы работаем: tasks, review, adr, research, .pm.json. Открыта одна категория из трёх, две другие перечислены поимённо, так что документ вне раскладки — однозначно своя тема. adr и research прогон больше не открывает ни одним проходом; docs/review остаётся читаемым, но как настройка конвейера, а не критерий. Цена записана и стала обязательной строкой границ покрытия: расхождение с записанным решением ловит теперь только сверка документации, а число под находкой обязано быть снято на этом прогоне, с приложенной командой. Классификация выдаёт задаче метку — small, medium, large. Прежние quick, standard и wide назывались ступенью и описывали ревью: как глубоко смотрим. Классифицируется же задача, и пока величина называлась свойством прогона, её естественно было пересчитывать на каждом прогоне — что конвейер и делал. Слово «ступень» удалено, а не оставлено синонимом: два имени одной вещи расходятся. Выводится метка из двух разведённых осей — размер (малое, среднее, крупное) и сложность (знакомое, незнакомое), — и равна максимуму по ним. Метка не синоним размера: малое незнакомое изменение получает large, трогая один узел, поэтому план печатает три строки с обоснованием каждая и выводить одну из другой запрещено. Оси остались русскими словами — это суждение прозой; метка английская — это идентификатор, который проходы сравнивают. Разметка переехала из ревью кода в шаг 4 пайплайна, сразу после propose. Она шла первым проходом каждого ревью кода, а перед ревью дизайна ту же величину называл сам пайплайн — то есть оркестратор, который только что довёл предложение до propose. Одно и то же измерялось дважды, и один из двух раз без разведённости с автором, ровно в той точке, ради которой разметчик заведён. Теперь запуск один на задачу, диффа он не видит, план обслуживает обе стадии, и метка после кода не пересматривается: расхождение факта с разметкой ловит журнал дефектов постфактум, как и всякую другую ошибку выбора. На диск план не пишется — четвёртый артефакт рядом с proposal, tasks и design пережил бы задачу и разошёлся бы с ней молча. Ревью дизайна тоже растёт меткой: small — specs, medium — плюс rubric, large — плюс architecture и вопрос автору о трёх формах решения. Раньше rubric и architecture включались одним условием, и medium получал ровно один проход, то есть не отличался от quick ничем. Разведены они потому, что зарабатывают на разном: рубрика порождает свойства узла и окупается уже на среднем изменении, её выход уезжает приёмочными критериями в tasks.md; архитектура отвечает на вопрос про второй способ, а он на среднем знакомом изменении отвечается «нет» ещё до запуска. small подешевел тремя способами сразу. Составом: приёмник тем не запускается, три темы ядра переходят к code сверкой по записанным инвариантам CLAUDE.md с потолком в одну находку, и это не «глубина ниже», а другой дом темы. Входом: specs читает только дельта-спеку, code — только индекс конвенций. Потолком: он появился у каждого опиниативного прохода, а не у одного basics, и у половин code он раздельный, потому что конвенционных находок больше по построению и в общем списке они вытеснили бы техническую половину. Сработавший потолок обязан быть объявлен строкой — молчащий срез неотличим от «больше не нашлось». Отрицательный тест small от этого стал жёстче, а не мягче: вопросы про обратимость миграции задавал приёмник тем, и на этой метке их не задаст никто. Пайплайн задачи вырос до двенадцати шагов. Тривиальность перестала решать состав ревью — она влияет только на explore; глубину обеих стадий называет метка. Проверено прогоном ревьюверов по готовому результату: девять расхождений найдено и починено — контракт находок печатал старый перечень проходов вместо плана по темам, три ссылки в task-batch указывали на шаг коммита вместо закрытия, запись changelog не переводила вопросы, адресованные passport и database, ops и adversary утверждали, что на нижних метках их вопросы задаёт basics, шаблон покрытия в review-code зашивал потолки small намертво, триггеры метки рассыпались на два списка против трёх, тема из директивы CLAUDE.md могла остаться без запуска исполнителя. Гейт зелёный: фронтматтеры, копии, одиннадцать диаграмм, ruff, pyrefly; docs.py прогнан на живом фикстуре и печатает категорию в отказе. Канон повышен до версии 6 с записью, выполнимой upgrade. Решения — 40–44. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+227
@@ -2707,3 +2707,230 @@ JJJ): у профиля обязан быть один правильный от
|
||||
147. **Снятая проверка называет, что осталось вместо неё.** Цель не проверяется
|
||||
— значит, за состав отвечают показ человеку и строка доклада; иначе
|
||||
послабление читается как «здесь можно не думать».
|
||||
|
||||
## 40. Три категории документов: не всякий документ — тема ревью (2026-08-07)
|
||||
|
||||
Решение 36 объявило: **каждый документ проекта — тема ревью**. Правило дало
|
||||
открытый список тем и сделало `docs/` конфигурацией конвейера — это работает и
|
||||
остаётся. Но оно же оказалось неверным ровно наполовину, и потому вредным
|
||||
целиком.
|
||||
|
||||
Паспорт и схему хранилища ревью читает, но темами они не являются: по ним нельзя
|
||||
сказать «в этом изменении сделано не так», они задают границу, по которой судит
|
||||
**чужая** тема. Журнал решений и журнал наблюдений ревью изменения не нужны
|
||||
вовсе: ADR объясняет прошлое решение, а не предъявляет требование к изменению.
|
||||
|
||||
Ломалось это механически. Разметчик, применявший правило буквально, обязан был
|
||||
либо завести фантомные темы `passport`, `adr`, `database`, `research` и
|
||||
продублировать ими работу тем `architecture` и `operations`, либо потерять четыре
|
||||
документа молча. Обе ветки случались; в собственном образце плана разметчика
|
||||
`docs/passport.md` не попадал ни строкой, а его же обязательная арифметика
|
||||
покрытия («документов найдено N, все N разнесены») при этом не сходилась.
|
||||
|
||||
**АЕАБА. Разрез один и проверяемый: можно ли по документу сказать «в этом
|
||||
изменении сделано не так».** Отсюда три категории. **Тема** — да, прямо
|
||||
(`conventions`, `security`, `architecture`, свои документы проекта). **Источник
|
||||
темы** — нет, но он задаёт границу для чужой темы (`passport`, `database`,
|
||||
`CLAUDE.md`, `openspec/specs/`). **Процессный документ** — нет, он про то, как мы
|
||||
работаем (`tasks/`, `review.*`, `adr.*`, `research.*`, `.pm.json`).
|
||||
|
||||
**АЕАББ. Открыта одна категория из трёх.** `источник` и `процессный` перечислены
|
||||
поимённо и проектом не пополняются; открыта только `тема`. Прежняя формулировка
|
||||
«не темы ровно две» противоречила собственной раскладке канона — `.pm.json` был
|
||||
третьим, и правило-исправление жило в чужом плагине, в коде `docs.py`. Теперь
|
||||
документ, которого нет в раскладке, — однозначно своя тема проекта, и решать
|
||||
нечего.
|
||||
|
||||
**АЕАБВ. «Не судит по нему» и «не открывает» — разные вещи.** `docs/review.*`
|
||||
проходы читают на каждом прогоне: там вопросы по темам, журнал дефектов, типовые
|
||||
узлы, типовые ложноположительные. Это чтение конвейером **своей обвязки**, а не
|
||||
критерия. `adr/`, `research/` и `tasks/` не открывает никто.
|
||||
|
||||
**АЕАБГ. Цена решения записана, а не подразумевается.** Расхождение изменения с
|
||||
записанным решением прогоном больше не ловится — это работа сверки документации
|
||||
между спринтами. Измеренные числа проекта из ревью тоже ушли: проход,
|
||||
опирающийся на число, обязан **снять его сам, на этом прогоне**, и приложить
|
||||
команду замера. Обе потери идут обязательными строками в границы покрытия
|
||||
каждого прогона, и пишет их триаж — не проход, потому что проход о том, чего в
|
||||
конвейере нет, пожаловаться не может.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
148. **Плоское правило, верное наполовину, хуже двух правил.** Оно не даёт
|
||||
половине случаев легального ответа, и исполнитель выбирает между двумя
|
||||
плохими ветками — фантомной сущностью и молчащей потерей. Заметно это
|
||||
становится не на определении, а на первом же образце вывода.
|
||||
149. **Открытым делается одно множество, а не все.** Открытый список ценен тем,
|
||||
что в него попадает незнакомое; если открыты все категории, незнакомое
|
||||
попадает в произвольную.
|
||||
150. **Отказ читать документ — тоже граница покрытия, и её пишет сток.** Строку
|
||||
«этого не смотрел никто» некому подать снизу: проход, которого нет, отчёта
|
||||
не присылает.
|
||||
|
||||
## 41. Разметка задачи: одна величина, посчитанная один раз (2026-08-07)
|
||||
|
||||
Разметка была стадией 0 **ревью кода** и платилась на каждом прогоне. Перед ревью
|
||||
дизайна ту же самую величину — «крупное или незнакомое?» — называл сам пайплайн
|
||||
задачи, то есть оркестратор, который только что довёл предложение до `propose`.
|
||||
Одно и то же измерялось дважды, и один из двух раз без разведённости с автором —
|
||||
ровно в той точке, ради которой разметчик и заведён.
|
||||
|
||||
**АЕАВА. Разметка идёт один раз на задачу, сразу после `propose`.** Её план
|
||||
обслуживает обе стадии ревью: состав ревью дизайна и таблицу тем для ревью кода.
|
||||
Диффа она не видит — кода ещё нет; размер оценивается по дельта-спекам и перечню
|
||||
границ задачи.
|
||||
|
||||
**АЕАВБ. Осей две, ступень — максимум по ним.** **Размер** (малое, среднее,
|
||||
крупное) — про объём; **сложность** (знакомое, незнакомое) — про то, известна ли
|
||||
форма решения заранее. Раньше обе были склеены в один вопрос «крупное **или**
|
||||
незнакомое?»: ответ получался тот же, но разметка не могла сказать «среднее, но
|
||||
совершенно знакомое» — а это и есть рабочее умолчание.
|
||||
|
||||
**АЕАВВ. Ступень после кода не пересматривается.** Дифф может выйти крупнее
|
||||
ожидания — ступень не двинется. Пересмотр означал бы либо второй запуск
|
||||
разметчика (то, ради устранения чего он и переехал), либо машинный порог, который
|
||||
на нетипичной задаче срабатывает не туда. Расхождение факта с разметкой ловит
|
||||
журнал дефектов, постфактум, — так же, как и всякую другую ошибку выбора ступени.
|
||||
|
||||
**АЕАВГ. План на диск не пишется.** Файл-план стал бы четвёртым артефактом рядом
|
||||
с `proposal.md`, `tasks.md` и `design.md`, пережил бы задачу и разошёлся бы с ней
|
||||
молча. Прервался пайплайн — разметка повторяется; это самый дешёвый его проход.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
151. **Величина, из которой выводится состав, считается один раз и одним
|
||||
агентом.** Два места, считающие одно и то же, расходятся; расходятся они
|
||||
молча, и побеждает то, у которого меньше разведённости с автором.
|
||||
152. **Разведённость — свойство момента, а не роли.** Тот же агент, спрошенный
|
||||
до написания кода и после, даёт разные ответы; переезд по времени сделал
|
||||
больше, чем сделал бы любой запрет.
|
||||
|
||||
## 42. `quick` стал дешевле `standard` тремя способами (2026-08-07)
|
||||
|
||||
`quick` и `standard` совпадали составом (шесть проходов) и различались глубиной
|
||||
трёх тем: сверка против разбора. На практике это означало один проход, задающий
|
||||
на один вопрос меньше, и потолок 4 вместо 2. Нижняя ступень не экономила почти
|
||||
ничего и называлась отдельной ступенью зря.
|
||||
|
||||
Отдельно выяснилось, что дешевизна конвейера держалась на двух заявленных
|
||||
рычагах — узкий вход и потолок находок, — и **оба применялись к одному проходу
|
||||
из шести**. У `specs` и `code` потолка не было вовсе, а вход `code` включал
|
||||
чтение дома конвенций «весь и целиком» на каждой задаче.
|
||||
|
||||
**АЕАГА. `quick` теряет приёмник тем.** Темы `security`, `operations` и
|
||||
`architecture` на этой ступени закрывает `code` сверкой с **записанными
|
||||
инвариантами** `CLAUDE.md`, потолком 1 находка на все три. Это не «глубина
|
||||
ниже» — это **другой дом темы**, куда более узкий, и в плане он так и называется.
|
||||
|
||||
**АЕАГБ. Приёмник тем запускается тогда и только тогда, когда ему есть что
|
||||
принимать.** Правило было в `wide` («нет своих тем проекта — не запускается») и
|
||||
теперь распространено на `quick`. Совпадение неслучайное: темы ядра `basics`
|
||||
держит ровно на одной ступени из трёх, а приёмником проектных тем работает на
|
||||
всех.
|
||||
|
||||
**АЕАГВ. Вход и потолок применены к каждому опиниативному проходу.** На `quick`
|
||||
`specs` читает только дельта-спеку, `code` — только индекс конвенций. Потолки
|
||||
напечатаны и раздельны по половинам `code`: 3 технических, 2 конвенционных, 1 по
|
||||
инвариантам. Раздельность обязательна — конвенционных находок больше по
|
||||
построению, и в общем списке они вытеснили бы техническую половину, чей пропуск
|
||||
дороже.
|
||||
|
||||
**АЕАГГ. Сработавший потолок объявляется.** Проход, срезавший находки, говорит
|
||||
строкой, сколько осталось за срезом и какого рода. Молчащий срез неотличим от
|
||||
«больше не нашлось» — тот же класс молчащего пропуска, против которого написан
|
||||
весь конвейер.
|
||||
|
||||
**АЕАГД. Отрицательный тест `quick` стал жёстче, а не мягче.** Вопросы «обратима
|
||||
ли миграция» и «что с записями новой версии после отката» задавал приёмник тем; на
|
||||
`quick` его нет. Значит изменение, которое не откатывается обратной правкой, на
|
||||
`quick` не идёт вовсе — каким бы малым оно ни было.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
153. **Ступень, не дающая экономии, не нужна.** Две ступени, различающиеся одним
|
||||
вопросом одного прохода, — это одна ступень с шумом в отчёте.
|
||||
154. **Рычаг, применённый к одному исполнителю, — не рычаг, а исключение.**
|
||||
Заявленный механизм экономии проверяется перечислением: к кому он применён и
|
||||
к кому нет.
|
||||
155. **Проход без потолка выдаёт столько находок, сколько нашёл поверхностей.**
|
||||
Ровно из-за этого был снят проход независимой реализации; тот же механизм
|
||||
работал у `code` и `specs` и не был замечен, потому что счёт никто не считал.
|
||||
|
||||
## 43. Ревью дизайна тоже растёт ступенями (2026-08-07)
|
||||
|
||||
Состав ревью дизайна включался одним условием: `specs` всегда, `rubric` и
|
||||
`architecture` — вместе, «при крупном или незнакомом». Значит `standard` получал
|
||||
на предложении ровно один проход, то есть не отличался от `quick` ничем.
|
||||
|
||||
**АЕАДА. Три ступени вместо двух: `quick` — `specs`; `standard` — плюс `rubric`;
|
||||
`wide` — плюс `architecture` и вопрос автору о трёх формах решения.**
|
||||
|
||||
**АЕАДБ. Рубрика съехала вниз, архитектура осталась наверху, и это не
|
||||
симметричная правка.** Они зарабатывают на разном. Рубрика порождает **свойства
|
||||
узла** и окупается уже на среднем изменении: её выход уезжает приёмочными
|
||||
критериями в `tasks.md` и работает потом на всей задаче. Архитектура отвечает на
|
||||
вопрос «не появился ли второй способ», а он на среднем знакомом изменении
|
||||
отвечается «нет» ещё до запуска — держать её ниже `wide` значит платить за
|
||||
предсказуемый ответ на каждой задаче.
|
||||
|
||||
**АЕАДВ. Тривиальность задачи больше не решает состав ревью.** Раньше она решала,
|
||||
звать ли ревью предложения вовсе; теперь глубину обеих стадий называет ступень, а
|
||||
тривиальная задача просто получает `quick`. «Пропустить ревью дизайна» и «пройти
|
||||
его одним самым дешёвым проходом» — разные вещи: сверка дельта-спек стоит
|
||||
меньше, чем разбор того, что она поймала бы на готовом коде.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
156. **Проходы, включаемые одним условием, стоит разводить по тому, на чём они
|
||||
зарабатывают.** Общее условие — признак того, что их не сравнивали между
|
||||
собой, а не того, что они равноценны.
|
||||
157. **Средняя ступень обязана отличаться от нижней на обеих стадиях.** Иначе
|
||||
«рабочее умолчание» отличается от исключения только именем.
|
||||
|
||||
## 44. Метка задачи: одно значение, по которому выбираются все ревьюверы (2026-08-07)
|
||||
|
||||
Решения 41–43 развели классификацию на две оси и свели состав обеих стадий ревью
|
||||
к их максимуму. Значения этого максимума назывались `quick`, `standard`, `wide`,
|
||||
а сам он — «ступень». Оба имени описывали **ревью**: как глубоко смотрим, на
|
||||
какой ступеньке идём. Классифицируется же при этом **задача**, и результат
|
||||
классификации принадлежит ей, а не прогону.
|
||||
|
||||
Расхождение не косметическое. Пока величина называлась свойством ревью, её было
|
||||
естественно пересчитать на каждом прогоне — что конвейер и делал, пока разметка
|
||||
не переехала к `propose`. Имя тянуло назад к устройству, из которого её только
|
||||
что вынули.
|
||||
|
||||
**АЕАЕА. Классификация выдаёт задаче метку: `small`, `medium` или `large`.**
|
||||
Метка принадлежит задаче, ставится один раз при разметке и дальше только
|
||||
читается. Все проходы обеих стадий получают её в задании и обязаны напечатать в
|
||||
границах покрытия.
|
||||
|
||||
**АЕАЕБ. Метка — единственный вход выбора исполнителей.** Ни класс задачи, ни её
|
||||
тип, ни тривиальность, ни ощущение важности состав больше не определяют. У
|
||||
конвейера один переключатель, и он напечатан в каждом отчёте.
|
||||
|
||||
**АЕАЕВ. Слово «ступень» удалено, а не оставлено синонимом.** Два имени одной
|
||||
вещи расходятся — это ровно решение #37 про тему и проход. Метка ordered: `small`
|
||||
< `medium` < `large`, и там, где нужен порядок, говорится «младшая» и «старшая
|
||||
метка», а не вводится второе существительное.
|
||||
|
||||
**АЕАЕГ. Метка — не синоним размера, и это записано там, где ошибиться легче
|
||||
всего.** Совпадают они в одном углу таблицы из трёх: малое **незнакомое**
|
||||
изменение получает `large`, трогая один узел. Поэтому план печатает три строки —
|
||||
размер, сложность, метка, — каждую со своим обоснованием, и выводить одну из
|
||||
другой запрещено. Проход, определивший объём диффа по метке, ошибётся именно на
|
||||
том случае, ради которого верхняя метка и заведена.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
158. **Имя величины должно называть её носителя, а не потребителя.** «Ступень
|
||||
ревью» звала пересчитывать себя на каждом прогоне ревью; «метка задачи»
|
||||
считается там же, где живёт задача.
|
||||
159. **Переключатель состава должен быть один и печатный.** Пока их два —
|
||||
тривиальность и ступень, — состав выводится из пересечения, а пересечение
|
||||
нигде не напечатано целиком.
|
||||
160. **Русские слова для осей, английские для значения.** Оси — суждение и
|
||||
читаются прозой (`малое`, `знакомое`); метка — идентификатор, который
|
||||
проходы сравнивают, и потому она английская. Тот же разрез, что «имена
|
||||
файлов английские, текст русский» в каноне, и он же снимает путаницу
|
||||
«крупное» против `large`.
|
||||
|
||||
Reference in New Issue
Block a user