61cd9fcd37ffa5aaaac5b0a6c2f0ce867dde933b
19
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4386eb3e1c
|
шов между плагинами: канон перестал называть имена проходов
av-dev-pm и av-dev-pipeline раздельны: канон работает без конвейера, конвейер без канона — поразрядно деградируя и называя это строкой. Но канон в шести местах называл конвейер поимённо, и одно из них — вывод docs.py пользователю: «свои темы проекта: … — их разбирает review-basics». Такая строка чинится не правкой файла, а недоумением на чужом проекте. Правило записано в canon.md, чтобы не отрастало заново. Общий словарь — имена тем и имена ступеней, и только они: ими проект настраивает ревью, вопросами по темам и триггерами профиля. Имён проходов канон не называет нигде. Направление несимметрично, и это верно: конвейер называет документы канона поимённо, потому что он их читатель, а обратной ссылки быть не может — документ живёт дольше, чем раскладка проходов. Что вычищено: имя review-basics в canon.md, в changelog версии 5 и в выводе docs.py; «её берёт basics» из таблицы ролей; описательные адресации того же класса — «архитектурный проход судит», «враждебный проход выдумает». Худшей была строка в skeletons.md «там идут враждебный, эксплуатационный и архитектурный проходы»: утверждение о составе ступени, живущее на стороне, которая о составе не знает. Строка таблицы «эксплуатационный проход ревью» стала «тема ревью operations» — заодно совпала со словарём, к которому tasks/SKILL.md отсылает как к единому дому. Отдельно — пример, нарушавший собственное правило. Объяснение, почему вопросы адресуются темам, звучало «вопрос, адресованный ops, перестал задаваться в тот день, когда ops уехал в верхнюю ступень»: правило про нестабильность имён, проиллюстрированное именем. Стало «адресованный проходу» и переживёт переименование. Починена и висячая ссылка: project-facts.md отсылал к таблице «Кто читает» в каноне, которой там нет — она была убрана правкой, вводившей темы, и по новому правилу её и не должно быть. Списка читателей не ведёт никто: читателя назначает план прогона. Тема 38 в DECISIONS.md, следствия 143-144. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a81dd1a5a7
|
ревью по темам: документ проекта стал направлением проверки
Замечено при сверке документов канона с составом ступеней: три документа остались без читателя ниже wide — security.md, database.md и adr/. Проект поддерживал их, а на 90% задач не открывал никто. Причина оказалась не в переезде проходов, а в том, как описан состав прогона. Список тем нигде не был записан: он существовал побочным продуктом списка проходов. Проход уезжал в верхнюю ступень — и тема уезжала с ним беззвучно. Отчёт честно говорил «ops не запускался» и не говорил «эксплуатацию не смотрел никто», а нужно второе. Теперь тема первична, проход вторичен — это правило 0 конвейера, а прогон описывается таблицей «тема → дом → глубина → кто закрывает», и таблица есть в каждом отчёте. Тема есть документ, список открытый. Всё, что проект кладёт в docs/, становится темой ревью; запретить нельзя, разрешения не надо. Не темы ровно две: docs/tasks/ и docs/review — настройка самого конвейера, слой над темами. Отсюда главное: docs/ перестал быть документацией и стал конфигурацией конвейера. Проект настраивает проверку тем, что пишет о себе, а не отдельным файлом настроек, который разошёлся бы с документами. Ядро — requirements, autotests, conventions, architecture, security, operations; всё сверх разбирает basics, потому что именных проходов конечное число, а тем столько, сколько заведёт проект. Тема живёт файлом или каталогом, на выбор проекта: docs/security.md и docs/security/ — одно и то же. Прежде форма была задана поимённо и обосновать её было нечем; заодно в TODO висел вопрос «а если architecture.md разрастётся». Теперь ответ механический: разросся — стал каталогом с README.md, и это не смена версии. Обе формы сразу — ошибка, docs.py её ловит. Заведён review-scope, sonnet, стадия 0, до гейта: находит документы, выводит темы, назначает глубины, выбирает ступень с обоснованием. Довод оказался сильнее синхронизации документов — до сих пор профиль называл тот же оркестратор, который написал код, то есть в точке выбора глубины проверки разведённости с автором не было вовсе, а решала она под давлением «я почти закончил». Вызывающий пайплайн профиль больше не передаёт. Поднять и понизить ступень разметчик вправе одинаково, но обоснование обязательно всегда. Sonnet ему хватает потому, что вывод устроен как список: каждый файл в docs/ обязан попасть в план темой или строкой «не тема, потому что», и план сверяется с ls docs/ за секунду. Выбор ступени — суждение, но у него три независимых корректора: отрицательный тест quick, правило «спорный случай вниз» и сигнал basics о заниженной ступени. Разметчик передаёт адреса, а не пересказ. Проект однажды уже держал review-brief.md и убрал его: второй дом расходится с первым и выглядит актуальным. Пересказ в задании — тот же посредник, живущий один прогон. Исключение одно: отсутствие дома, этого проход сам дёшево не выяснит. quick и standard совпали составом и разошлись глубиной — иначе требование «нижние ступени закрывают все темы, просто не так глубоко» не выполняется. Глубин три, и они про способ доказательства, а не про старательность: сверка (открыть дом, открыть дифф, сравнить), разбор (построить сценарий рассуждением), доказательство (прогнать, померить, построить путь). Третья есть только в wide. Цена принята: это единственное место, где профиль не выводится из списка проходов, поэтому глубина объявляется в отчёте наравне со ступенью. review-code переписан, и это оказалось крупнее исходной находки: код как код не читал никто. specs сверял с требованиями, basics — с отказами окружения, architecture — с устройством, а code был проходом только по прозаическим конвенциям и прямо объявлял, что рантайм и логика не его. «Здесь ошибка в логике» не говорил вообще никто. Теперь у прохода две половины: девять классов технического дефекта (необработанная ветка отказа, пустое и нулевое, граница диапазона, перепутанный операнд, неосвобождённый ресурс, изменение под итерацией, неверно применённый интерфейс библиотеки, недостижимая ветка, «сделано соседнее») и прежняя сверка с конвенциями. Модель поднята до opus по признаку темы 35: цена пропущенной находки — дефект в проде. Канон повышен до версии 5: форма дома на выбор, открытый список тем, AGENTS.md законно лежит рядом с CLAUDE.md, «Вопросы к проходам» → «Вопросы по темам» (имя прохода переезд не переживает, тема переживает), «Недоступно проверке» — тоже по темам. docs.py переписан под темы: ловит двойной дом, принимает обе формы, перечисляет свои темы проекта вместо «файл вне канона». Побочно закрыт давний пункт TODO про каталожную форму architecture.md — решать больше нечего. Прогон от всего этого стал дороже, а не дешевле, впервые за сессию: плюс scope в голове каждого прогона, плюс code на opus, плюс basics теперь и в quick. Куплены разведённость выбора ступени, видимость непокрытых тем и технический разбор кода, которого не было вовсе. Тема 36 в DECISIONS.md, следствия 137-140. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
21b840a8e4
|
профили ревью: тяжёлые проходы в верхнюю ступень, на умолчании — один базовый
Тема 33 сняла самую большую разовую статью расхода, но не тронула главную — частоту. Меряющая пара стояла в standard, то есть на большинстве задач, и именно она делала прогон долгим: два прохода держат машину, идут цепочкой и доказывают находки запуском. Цель разбора названа прямо: лучше поправить в следующей задаче, чем держать одну два часа. adversary и ops переехали в wide. Стадия осталась самой урожайной за всю историю замеров — пять из семи выживших находок дозапуска и единственная находка про молчаливый старт отката, — но её ценность оплачивается на каждой задаче, а получается на немногих. Решение по цене, не по ценности. Заведён review-basics: мелкая осадка двух тяжёлых проходов, без единого запуска. Стоит только в standard. Восемь вопросов, на которые отвечают чтением: таймаут и отказ соседа, идемпотентность и одновременная запись, остановка на середине, частичный откат при двух версиях, наблюдаемость и тишина, очевидный рост объёма, второй способ мимо единой точки (грепом, не картой), что отсюда удалить. Потолок 4 находки, машину не держит, ничего не меряет. Вопрос про частичный откат — не для полноты списка. Без него правило «миграция схемы не поднимает ступень» рассыпалось бы: раньше миграцию разбирал ops, а он теперь наверху. Проход заведён затем, чтобы у standard остался хоть один взгляд на ось времени. Модель у него верхняя, opus, и это не спорит со словом «средний»: усилие режется входом и потолком, а не моделью. Дешёвая модель на опиниативном проходе платит триажем — это записанный замер, отменять его без нового замера нечем. Лестница вышла 4/5/7. Главный выигрыш не в числе проходов, а в том, что из standard ушла цепочка: теперь там гейт, три прохода одним сообщением и триаж — граф плоский, ждать некому. Правило выбора ступени переписано на два вопроса, и объём изменения вошёл в него впервые. Крупное или незнакомое — трогает несколько узлов, переносит ответственность, форму решения нащупывают по ходу — это wide, и он рассчитан на 5-10% задач. Мелкое — один узел, форма очевидна заранее, откат сводится к обратной правке — quick. Всё остальное standard, рабочее умолчание. Раньше ступень выбиралась только по классу изменения и на размер смотреть запрещала; теперь признаков два: класс отвечает за обратимость, объём — за цену разбирательства. Отрицательный тест сохранил прежнюю мудрость в новой рамке: что после мерджа не откатывается обратной правкой — не quick, каким бы маленьким ни был дифф. Три строки миграции идут в standard. Спорный случай решается вниз, и асимметрия объяснена ценой: ошибка в сторону standard стоит находки на следующей задаче, ошибка в обратную — трёх тяжёлых проходов на каждой задаче, выбранной неверно. Сделка записана вместе с обратной связью, иначе это тихая потеря качества. На quick и standard не проверяется ничего, что требует запуска: построенный путь, эксперимент против драйвера, любое число. Это самая крупная граница покрытия конвейера, и она идёт строкой в каждом таком прогоне поимённо. Сигналов о том, что ступень занижена, два: журнал дефектов в docs/review.md и сам basics — он единственный, кто смотрит на дифф целиком на нижних ступенях, и обязан сказать строкой, если задача выглядит крупнее профиля. Побочно: условие профиля design то же самое, так что rubric и architecture на предложении тоже упали до 5-10% задач. Тема 34 в DECISIONS.md, следствия 130-133. Версия канона не поднята; инструкция проекту дописана в пункт 8 записи «Версия 4». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ea84a4fbb3
|
стоимость ревью: снят проход независимой реализации и самая дорогая модель
Прогоны стали долгими, а счёт в токенах заметным. Разбор шёл не по находкам, а по статьям расхода. Две названы прямо: убрать 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> |
||
|
|
cbfae90f3f
|
словарь: пять слов сняты, девять закрыты списком вместо оговорки «прижилось»
Проход упрощения уткнулся в один класс у всех пяти агентов: слово, живущее в трёх-шести файлах разом. Правка в одном месте развела бы словарь, правка во всех — уже не упрощение текста скилла. Каждый честно остановился и записал слово в отчёт, и одни и те же слова всплыли в разных отчётах. Разобрано этим проходом. Причина, по которой они вообще накопились, оказалась в самом уставе языка. Он разрешал не переводить «термин, у которого нет точного русского эквивалента и который в команде уже прижился». Проверить это нельзя: прижившимся выглядит любое слово, встреченное трижды, — и ровно так рассудили пять агентов подряд, каждый независимо. Оговорка заменена закрытым списком из девяти терминов с колонкой «что называет»: интейк, триаж, провенанс, дедуп, чек-лист, дифф, промпт, сущности OpenSpec, роды проходов ревью. Интейк оставлен потому, что «заведение» называет создание файла, и слить их значит смешать две операции; провенанс — потому что «источник» рядом называет саму запись, а не свойство числа. Слово не из списка и не из таблицы имён вещей — находка, а не стиль. Список заведён домом язык-словарь в language.md и копией в уставе doc-wording. Копия обязательна: агент работает в репозитории проекта, где плагина может не быть, и без списка предъявил бы интейк как англицизм. Снято пять слов, 29 мест: конфляция → смешение, декорреляция → разведённость, непоймание → почему не поймали, эвал-сет → проверочный набор, гайд → руководство. Латинизм или калька при живом русском слове в каждом случае. Разбор декорреляции показателен: проект уже владел нужным словом — «агенты разведены по глубине», «разведены по охвату» — и держал рядом латинский синоним того же понятия. Это не англицизм, а второй дом для слова. Непоймание снято ещё и потому, что форма журнала дефектов, которую канон кладёт в проекты, спрашивает «Почему не поймали», а проза рядом называла это «причиной непоймания». Скелет и проза о скелете говорили разными словами. Снятое записано вместе с оставленным, в одном списке и с заменой каждого. Иначе слово возвращается: из текстов оно уходит, но ничто не мешает следующему проходу завести его заново — оно ведь короткое и точное на вид. Тема 32 в DECISIONS.md, следствия 124-126. Нумерация правил в уставе doc-wording сдвинута: словарь встал шестым, жаргон и далее уехали на единицу. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
47a2f3de63
|
язык скиллов av-dev-pm: проход упрощения пятью агентами и разбор находок
Эксперимент: по сабагенту на каждый скилл av-dev-pm, задача — переписать текст более простыми словами, но только там, где уверен и без потери смысла и точности. Нормой служил устав языка самого проекта, language.md, включая его раздел «Порог правки»: правка без нарушенного правила не делается. 36 правок в двенадцати файлах, +64/-63 — почти строго замена, а не переписывание. Правили залог (пассив с названным деятелем в творительном), отглагольные существительные, параллельность перечней, канцелярит «является», пару garden-path и одно двойное отрицание. Контракт не задет нигде: в диффе нет изменённых строк-заголовков, а код-спаны встречаются ровно парой минус-плюс, то есть ни имя, ни флаг, ни путь не переписаны. Отчёты «что рассматривал и не тронул» вышли длиннее отчётов о правках у всех пятерых, и это главный результат прогона. Самый частый повод остановиться — слово, живущее в четырёх файлах: конфляция, интейк, провенанс, непоймание. Правка в одном месте развела бы словарь, а править все — уже не упрощение текста скилла, а сквозной проход по репозиторию. Второй повод — формулировка, дословно повторённая в соседнем плагине: декорреляция, материализация нерешённого, «при расхождении прав текст». Шестой агент проверил все 36 правок и нашёл четыре. Перестановка слов в task-research.md развела формулу с её домом: «число без источника проход ревью обязан читать как условие» стоит в canon.md и в уставе doc-consistency, который прямо ссылается на канон как на источник. Откачено — это ровно тот класс расхождения, который сам doc-consistency и ловит. «Держит H1, мету и индекс в согласии» — управление требует дополнения, а language.md в разделе англицизмов прямо оговаривает: русский аналог звучит коряво — остаётся термин. Взят третий вариант, «согласованными». В skeletons.md «правка тянет запись, и она называет» — местоимение указывает на два женских существительных сразу. Стало «и запись называет». Четвёртая находка не откачена: правка в init/SKILL.md хорошая, но развела конструкцию с близнецом в canon/SKILL.md — выровнена вторая половина. Побочно найдена старая логическая инверсия в DECISIONS.md, решение U: «становится неотличимым, только если отрицание обязательно» — смысл вывернут, в docs/SKILL.md и во второй записи журнала он правильный. Починено. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
354a6b03d5
|
канон 4: слаг подкреплён проверкой, обещанный судья заведён
Оба пункта заметок оказались одним классом: правило записано и никем не исполняется. Слаги. canon.md говорил «слаги файлов, capability и задач — английские, kebab-case» одной строкой в хвосте раскладки, а docs.py имён файлов не смотрел вовсе. Итог нашёлся в самом плагине: единственный пример ADR в скилле docs назывался ADR-2026-08-03-ochered-tablicej. Раскладка канона при этом приглашала к нарушению — в схеме стояли плейсхолдеры <тема>.md, то есть слово «тема» по-русски там, где надо писать <slug>. docs.py check теперь смотрит имена: кириллица и не-kebab-case жёстко, форма ADR-ГГГГ-ММ-ДД-slug.md жёстко, транслит эвристикой, то есть замечанием. Проверяются docs/conventions, docs/research, docs/adr и имена capability; каталог задач не трогается — его слаги ведёт tasks.py. Набор маркеров транслита подобран так, чтобы ложных срабатываний не было вовсе: выброшены ost (ловит post, cost), sch (schema), ya (yaml), nost (nostalgia), хвост ii (radii). Цена названа в комментарии — sostoyanie-partii проходит мимо. Правило, краснеющее на правде, приучает пролистывать весь блок, и это дороже пропуска. Агенты. В canon.md есть таблица «Что проверяет машина, а что человек», и её правая колонка — смысловой дубль, поведение в architecture.md, протухший факт, достаточность честной строки — три версии описывала работу, которую никто не делал: скилл canon предлагал агенту судить об этом самому, то есть проверять то, что он же и писал. Заведены двое, разрез по глубине — тот же довод, что развёл task-form и doc-wording. doc-consistency читает docs/ и openspec/, сверяет документы между собой (факт в двух домах, прямое противоречие, поведение в обзоре вместо спек, ADR без ссылки на design.md и без парного статуса, число без провенанса, заглушка вместо честной строки) и зовётся на шаге синка документации. doc-code-drift читает репозиторий, отвечает на «этот факт ещё верен» и зовётся раз в спринт на сессии. Перечень фактов, сверяемых с кодом, закрыт: имя ветки, команды, пути, зависимости поимённо, настройки с числом, единые точки проекта, capability, проверяемые инварианты. «Сверить архитектуру с кодом» — задача без дна, и агент, которому её поставили, выдаёт правдоподобную труху. Отсюда форма его доклада: начинается таблицей проверенного, а не находками, — по ней видно, чего он не смотрел. Карта домов уехала в устав doc-consistency помеченной копией: устав ссылался на файл плагина, а агент работает в репозитории проекта, где плагина может не быть. copies.py её сторожит. Попутно: докстрока copies.py показывала закрывающие маркеры как <!-- /дом -->, а код требует <!-- /дом: <id> -->. Нашлось первой же попыткой ими воспользоваться. DECISIONS тема 28 (ННОО–ХХЦЦ, следствия 105–108). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
069205ac69
|
канон 4: секция «Сопровождение», «Готово» вниз, порядок закреплён
healthlog уже переехал на канон 3, а переименование секции я внёс правкой записи версии 3 задним числом — то есть переписал текст, по которому он ехал. Посылка «ни один проект на каноне 3 не стоит» была ложной, решение ШШШ отменено. Запись версии — черновик ровно до первого переехавшего проекта. После этого она история, и любое изменение канона заводит новую версию, даже если меняется одно слово. Проверять дёшево: grep '"canon"' по живым проектам. Дорого обратное — проект, повышенный по тексту, которого больше не существует, невоспроизводим. Запись версии 3 восстановлена дословно (Разработка | Tooling), переименование уехало в версию 4. jellybit, стоящий на каноне 2, прочтёт обе записи подряд и заведёт Разработка, чтобы через шаг переименовать; в шаг версии 3 добавлена оговорка «едешь сразу на 4 — заводи Готово последней и не переставляй дважды». «Готово» переехало вниз, и порядок секций стал каноническим. Достигнутое копится: через год этой секции больше, чем всех остальных вместе, и стоя первой она отодвигает за экран то, ради чего роадмап открывают чаще всего. Порядок проверяет roadmap_lint, переставляет check --fix — вместе с содержимым секций, потому что двигать десяток строк руками это работа, на которой ошибаются. Чужую секцию перестановка не трогает вовсе: её место в порядке неизвестно. Индексы позиций считаются из самого кортежа: ACHIEVED был 0 и стал 3, хардкод пережил бы перестановку молча и сломал бы close. Обкатка нашла два дефекта оформления, оба порождённые самой перестановкой. Отбивка нужна и перед заголовком — сдвиг блоков ставит два заголовка вплотную. Удаление строки индекса оставляет две пустые подряд, и пустоты копятся. Проверка оформления теперь сверяется с самим нормализатором, а не своим набором условий: два описания одного правила разъедутся, и check начнёт молчать о том, что --fix правит. CANON_VERSION = 4 в docs.py, примеры .pm.json в canon.md и skeletons.md. DECISIONS тема 26 (ЭЭЭ, ЮЮЮ, ЯЯЯ, следствия 98–100). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5bf599a767
|
верхняя ступень ревью задана тестом, а не списком
«Идентичность, слияние, разбор» пришли из одного проекта, и в общем виде формулировка не читалась: вопрос «как применить это к моему проекту» не имел ответа в тексте. Теперь класс задан тремя условиями, не зависящими ни от домена, ни от языка: вариантов несколько и оба защитимы; спека между ними не выбирает; неверный выбор не падает, а даёт правдоподобный результат и молча меняет смысл данных. Отрицательный тест сильнее трёх положительных: то, что красит гейт, роняет запрос или ломает тест, в класс не входит — это ловят проходы дешевле. Отсюда же и причина, по которой класс достался самому дорогому проходу: независимая реализация выберет другой вариант, и дифф между вариантами и есть находка; там, где вариант один, она совпадёт с существующей. Три слова остались как три места, где такие правила водятся — граница, где данные входят или встречаются: состав ключа и нормализация перед сравнением; победитель конфликта и тай-брейк при равенстве; границы токенов и неоднозначный вход. Проект перечисляет свои места в docs/review.md, и перечень производен от теста, а не заменяет его. Две оговорки, без которых правило вырождается: - триггер — новое или изменённое по существу правило, а не код рядом с ним; иначе проект, чей домен и состоит из таких правил, всегда в deep; - проект, где такого класса нет вовсе, deep не запускает никогда, и это законное состояние, а не недонастройка. review-reimpl получил тот же тест и право сказать первой строкой, что позвали не на его класс, — строкой в границы покрытия, а не отказом работать. DECISIONS 18, XXX и следствия 76–77. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
cc173b6b94
|
ступень ревью поднимает проход, а не риск
Полный набор гонялся чаще, чем оправдано, и размер задач тут вторая причина, не первая. Первая — триггеры: миграция схемы, публичный контракт и инвариант поднимали ступень, не добавляя ни одного прохода. Миграцию гоняет gate шагом миграций и разбирает ops, контракт сверяет specs направлением code→spec, инвариант даёт основание для critical любому проходу — все трое уже в standard. На проекте с базой и эндпоинтами верхняя ступень оказывалась не исключением, а умолчанием: правило объявляло исключением то, что происходит всегда. Теперь ступень поднимает то, что даёт работу новому проходу. wide означает ровно одно — изменение вводит новое понятие или структурную единицу; добавить поле в существующий ответ это не концепт. standard стал рабочим умолчанием. Проект, где изменение контракта и правда архитектурное, поднимает его сам в docs/review.md — уточнением, а не возвратом прежнего умолчания. Чекпоинт design получил то же условие: specs идёт всегда, rubric и architecture — только при новом понятии. Он стоит на каждой задаче, поэтому при мелкой нарезке три прохода умножаются на число задач. Со стороны задач — шов нарезки: тест декомпозиции отвечает, допустим ли разрез, шов отвечает, где его провести. Резать по границе, за которой падает ступень; не резать, когда обе половины остаются в одной — костяк из четырёх проходов платится за каждую задачу, и такой разрез делает ревью дороже. Порога в числе границ нет по тому же принципу, что в теме 16: размер не триггер. Дешёвое место заметить разнородную задачу — показ набора спринта, там «Затрагивает» уже написан, а предложение ещё не заведено. Правило выведено из состава проходов, а не из статистики прогонов — замер остаётся за обкаткой. DECISIONS 18, RRR–WWW и следствия 72–75; JJJ темы 17 помечен как пересмотренный. Шаг про «Триггеры профиля» дописан в ещё не выкаченную версию 3 канона, а не отдельной версией. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
b99c0c2366
|
канон версии 3: роадмап, род работы, границы задачи
Три изменения одной версией, потому что все три про одно — можно ли оценить задачу, не открывая код. PLAN.md → ROADMAP.md. Слово «план» значило в репозитории три разных вещи: оглавление целей, план реализации внутри задачи и PLAN.json разовой адаптации. Переименовано целиком — ключ конфига tasks.plan → tasks.roadmap, --index roadmap, --roadmap-sections, --roadmap. Старый ключ в docs/.pm.json не игнорируется молча: скрипт останавливается кодом 3 и называет переименование, иначе проект искал бы опечатку там, где на самом деле версия канона. Род работы — тег kind:feature|fix|chore|research, вторая ось поверх типа записи. В один префикс их не свести: идея бывает про функцию, эпик функцией и является. Дом — тег, потому что теги здесь единственный механизм разметки, а list --kind работает даром; цена принята — в строку индекса род не попадает. Словарь закрыт, иначе он разъедется на bug/bugfix/fix/defect. Отдельно легализован chore: у него «что станет наблюдаемо иначе» отвечается разработчику, а раньше такие задачи либо не заводились, либо придумывали себе пользовательскую пользу — и это второе хуже, оно проходит проверку. Раздел «Затрагивает» — границы, которых изменение касается: эндпоинт, таблица и миграция, формат на диске, публичный тип пакета. Без него задача оценивается по объёму текста, а не по объёму поверхности. Механизируется только наличие непустого раздела: полноту перечня машина не видит. Род и границы требуются к взятию в спринт, а не к заведению — тот же приём, что уже работает для критериев приёмки, и по той же причине. check о пропаже только напоминает: иначе два живых проекта покраснели бы на 98 задачах, заведённых до этого решения. Плюс правила языка задач: англицизм, у которого есть русское слово, заменяется; термин не из паспорта, архитектуры или конвенций вводится строкой или не употребляется; задача, которую не удаётся сказать просто, чаще всего не одна задача. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
84134cac1e
|
ревью: ступень wide, цвета по модели, проверка фронтматтеров
Прыжок standard → deep стоил самого дорогого прохода конвейера, а платить приходилось за одну архитектурную находку: изменений, которые трогают публичный контракт, но не вводят нового правила слияния, — большинство. Ступень wide это standard плюс architecture (вход шире диффа, отсюда имя), семь проходов против восьми. Заодно вычистилась давняя неровность: триггер reimpl стоял внутри deep, и профиль означал то семь проходов, то восемь — реестр состава, который «сверяется взглядом до коммита», проверять было нечем. Теперь условие «новое правило идентичности, слияния или разбора» выбирает профиль, reimpl в deep безусловен и есть единственное отличие от wide. Барьер стоимости остался только в deep: в wide за ним стоял бы один дешёвый проход с потолком в 3 находки, а барьер сериализует то, что могло идти разом. Цвет charter'а теперь кодирует модель, а не роль: sonnet → green, opus → yellow, fable → red. Роль видна из имени, стоимость прогона — ниоткуда, а список агентов читается взглядом. scripts/frontmatter.py ловит три класса ошибок, невидимых при чтении: - двоеточие с пробелом в незакавыченном описании — для YAML это вложенное отображение, а не текст. Так было написано три описания из четырнадцати, и читались они правильно; - name, разошедшееся с именем каталога скилла или файла charter'а; - цвет, не отвечающий модели: он ставится один раз при заведении charter'а, а модель потом двигает калибровка. Обе ветки проверены, коды выхода — общий словарь. Триггеры профиля в canon.md и skeletons.md подтянуты под wide. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
67cfa45162
|
канон 2: шапка ADR — мета-блоком, у статуса появился дом
Поля Дата и Источник приведены к общей форме меты (поле на строку, имя жирным) — той же, что у задачи и у записи журнала дефектов. Существеннее второе. Правило «передумали — новая запись, старая получает статус» жило в каноне с первой версии, но места под статус шаблон не отводил: каждая запись изобретала своё — то абзацем, то заголовком, — а колонка «Статус» таблицы adr/README.md обязана его показывать и брала оттуда, где он у каждого свой. Теперь статус — такое же поле шапки, у активной записи его нет. Правка ушла в дом (canon.md, раздел adr/) и в оба скелета: template.md и «Соглашения» в adr/README.md. Скелеты уезжают в репозиторий проекта, поэтому версия канона поднята до 2 с записью в changelog: что добавилось, что переехало и три шага проекту. Копии под маркерами не тронуты — copies.py дословность подтверждает. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
885981ca39
|
проверка копий правил: маркеры дома и копии, побайтовая сверка
Разделение плагинов оставлено, цена названа: пять симметричных контрактов в двух домах, два уже разошлись — форма журнала дефектов потеряла в копии поле «Причина», список читателей docs/research/ потерял specs. Оба раза копия выглядела актуальной и прошла мимо трёх ревью. scripts/copies.py требует побайтового совпадения текста между маркерами. Комментарии, а не манифест копий: маркер уезжает в репозиторий проекта вместе со скелетом и там полезен — говорит, что у текста есть дом. Идентификатор строгий и повторяется в закрывающем маркере. Иначе документация о самом механизме объявляет дом и роняет проверку: это случилось на первом же прогоне, README объявил дом примером. Ограда блока кода в сверку не входит: в доме текст обрамлён своей оградой, в скелете лежит внутри чужой, объемлющей. Помечены два контракта. Второй пришлось сперва сделать дословным: копия говорила «обязателен статус», дом — «обязателен статус „заменено на“». Проверка не ловит копию, которую забыли пометить, — это сказано вслух, иначе зелёный прогон читался бы как «копий больше нет». И не заменяет запись в журнал версий канона: она видит, что копия отстала, но не что проект унёс старую версию. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5dcf40d8af
|
ревью зависимостей: одна настоящая протечка, неисполнимая деградация, две разошедшиеся копии
Целевая картина проверена по коду и текстам. av-dev-git ни от чего не зависит. av-dev-pipeline проходим на задаче, заданной одной строкой текста, — кроме одного места. Третья цель в исходной формулировке недостижима, и поправлена формулировка, а не картина. av-dev-pm владеет docs/review.md — конфигурационным файлом конвейера с «Вопросами к проходам» и «Триггерами профиля», то есть знает проходы поимённо по построению. Кто-то этим словарём владеть обязан. Честная формулировка: pm не зовёт пайплайн и не требует его наличия — и она выполняется. Настоящая протечка была одна: опоры приёмки в «Стимулах» и sprint.md держались на отчёте триажа по конкретному OpenSpec-пути. В проекте без конвейера защита от занижения урожая исчезала молча. Теперь опора названа абстрактно, путь дан частным случаем, отсутствие конвейера обязано попадать строкой в доклад спринта. Ветка деградации шага 9 была неисполнима ровно в том случае, ради которого написана: «плагина нет — открой av-dev-pm/skills/canon/references/canon.md», путь в дерево маркетплейса. Пайплайн теперь ходит в свой project-facts.md, а ссылки в чужой плагин даются через Skill. Две симметричные копии уже разошлись: форма журнала дефектов (шесть полей против пяти, «Причина» потеряна) и читатели docs/research/ («specs» выпал). Дома назначены, копии помечены, обязанность тянуть запись в журнал версий записана. Плюс: пайплайн не называет items/ и SPRINT.md — их имена проект вправе сменить; манифесты объявили av-dev-pm опциональным и приём задачи текстом. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1fb006df4a
|
ревью двумя проходами: 20 находок, все починены
Два независимых сабагента на av-dev-pm и av-dev-pipeline. Две находки нашли оба. Главная — моя же перестановка закрытия за коммит сломала reopen и батч. close печатал «дорога назад из git», а reopen искал коммит удаления, которого в новом порядке ещё нет: шаг 11 последний, учёт остаётся незакоммиченным. Проверено прогоном — отказ кодом 2 на свежезакрытой задаче. Тем же грязным деревом ломались rebase и worktree remove в батче: каждая закрывшая задачу ветка уехала бы в провалившиеся. Починено с обеих сторон: reopen берёт текст из HEAD, если коммита удаления нет, а шаг 11 коммитит учёт вторым коммитом. Вторая — канонический пример docs/.pm.json убивал tasks.py. Четыре документа показывали ключ tasks.sections, которого скрипт не знает: неизвестный ключ это код 3 на любой команде. Проект, заведённый по канону дословно, остался бы без работы с задачами, а docs.py при этом печатал «канон соблюдён». Секции живут в заголовках индекса и второго дома не получают. Остальные восемнадцать: init писал конфиг в упразднённый .tasks.json; looks_like_tasks не видел переименованный индекс; урожай спринта терял автотег после sprint close; ответ на вопрос по инструкции оставлял задачу незабираемой; adopt требовал недостижимого зелёного; путь отчёта триажа не переживал archive; review-specs не имел режима для стыка после слияния; три остатка «шаг 9а» несли предкоммитную позицию закрытия; sprint.md отрицал сам себя в пункте «Сделана». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0eab075f84
|
починены находки второго ревью: цикл закрытия задачи и три отсутствовавших слота
- task-pipeline и task-batch запрещали шаг, который сами же добавили: раздел границ и финальный доклад переписаны под снятую границу приёмки - «триаж сводит строки в одну» противоречило «не сливает» — деградация снова поразрядная во всех трёх местах - канон не требовал в CLAUDE.md имени основной ветки, testdata и запретов, а скелета CLAUDE.md не было вовсе — заведён - обратимость жила в двух домах, читатели ходили в пустой; единственный дом теперь CLAUDE.md - заведены слоты «Единые точки проекта» и «Триггеры профиля», куда charter'ы слали, а канон их не создавал - блок «Вопросы к проходам» стал частью задания прохода: за ним ходили двое из девяти - чек-лист синка и правило «замер + настройка» сведены к одному дому; plugin.json больше не про бриф |
||
|
|
9cef45252c
|
av-dev-pipeline: бриф удалён, проходы читают документы канона напрямую
- удалены скилл project-brief и контракт брифа; вместо них references/ project-facts.md — карта «что нужно проходу → где лежит» и таблица поразрядной деградации по документам - девять charter'ов, review-pipeline, task-pipeline и task-batch переписаны на пути канона; OpenSpec стал объявленной предпосылкой без ветки деградации - шаг синка документации переписан в построчный доклад, закрытие задачи — вызовом скилла av-dev-pm:tasks вместо строки-слота из CLAUDE.md - по находкам ревью: docs.py звал tasks.py из чужого каталога и выдавал его отказ окружения за дрейф; сверка миграций не видела рабочее дерево; плейсхолдер краснел вместо замечания; сверка capability проходила по совпадению с именем пакета; tasks.py не читал docs/.pm.json; скилл docs пересказывал канон в пяти местах |
||
|
|
ad1779b81f
|
av-dev-pm: плагин переименован, заведены канон документов и скиллы init/canon/docs
- av-dev-tasks → av-dev-pm; канон определён единственным reference-файлом, который читают все три новых скилла - canon: check/adopt/upgrade плюс docs.py — раскладка, битые ссылки, версия, маркеры долга, сверки миграций и capability с документацией - tasks и session: путь docs/tasks жёсткий, конфиг переехал в docs/.pm.json, слот «Команда учёта задач» убран в пользу вызова скилла, раздел «Стимулы» переписан под совпавших приёмщика и исполнителя |