- DECISIONS.md: 29 решений по восьми темам, каждое с причиной; две отменённые версии сохранены с объяснением отмены - TODO.md: план в порядке выката, замер блокирует переезд jellybit
55 KiB
Решения по устройству процесса
Журнал согласований: что решено, почему и что из этого следует. Пишется по ходу разбора тем, одна тема — один раздел. Причина обязательна: через месяц она забывается раньше факта.
Незакрытые остатки прошлого захода — REMAINING.md.
Требования, зафиксированные по ходу
Не решения — вход, который обязан быть удовлетворён и разбирается в названной теме.
Т1. Адаптация и проверка проекта под канон — обязательный скилл. Нужно уметь прийти в любой старый проект и перевести его на текущие рельсы. Канон при этом сам будет меняться, поэтому уже приведённые проекты тоже должны повышаться до новых версий. Разбирается в теме 5 (старт и жизненный цикл проекта).
Следствия, которые из этого уже видны:
- У канона обязана быть версия, а у проекта — отметка, под какую он приведён. Иначе «соответствует канону» не имеет определённого ответа: сравнение идёт с тем, что модель помнит сейчас, а это и есть дрейф.
- Журнал изменений канона — как миграции. Каждое повышение версии несёт запись «что добавилось, что переехало, что удалено, что сделать проекту». Без него адаптация переизобретается на каждом проекте.
- Отметка версии машиночитаема.
.docs.jsonотвергнут как указатель путей (решение F), но отметка версии — другое: её читает скрипт, и разбирать прозуCLAUDE.mdдля этого не нужно. Прецедент —.tasks.json. - Операций три:
check(соответствие текущему канону),adopt(перевод чужой раскладки),upgrade(повышение с версии N до M по журналу). Первая и третья — одно сравнение с разными исходами. - Механизируемое и суждение не смешивать. Скрипт проверяет пути, лишние
файлы, битые ссылки, версию. Агент судит о смысловых дублях (
docs/specs/ recognition.mdпротив capabilityrecognition) и об оставшемся поведении вarchitecture.md. Скрипт, отчитавшийся «канон соблюдён» на проекте с тремя лишними файлами, хуже отсутствующего. - Границы плагинов:
docs/tasks/— часть канона документов, но владеет имav-dev-tasksсо своимtasks.py adopt. Два плагина сходятся на одном каталоге. Тема 7.
1. Статус OpenSpec (2026-08-03)
Что было
OpenSpec несёт оба проекта: healthlog — 5 capability, 3530 строк спек, 9
архивных change за две недели; jellybit — 11 capability, 3895 строк, 43 архивных
change. При этом в трёх местах плагина написана ветка «проект без OpenSpec»
(task-pipeline предпосылки, review-pipeline предпосылки, task-batch
предпосылки) — и не исполнялась ни разу.
Проектные факты живут в пяти домах: CLAUDE.md, docs/architecture.md,
openspec/specs/, openspec/config.yaml → context, и планируется шестой —
docs/review-brief.md.
Расхождение измерено: у healthlog раздел «Хранилище» в docs/architecture.md —
950 строк (377–1328) против openspec/specs/storage/spec.md на 1337 строк. Два
описания одного поведения, никем не сверяемые. У jellybit того же нет:
docs/specs/architecture.md — 300 строк обзора, детали в 11 спеках. Проект с
43 изменениями держит архитектуру втрое короче проекта с 9.
Решено
A. OpenSpec — жёсткая предпосылка av-dev-pipeline. Ветки деградации
удаляются, вместо них объявленная зависимость и проверка на старте. Зависимость
на уровне плагина, а не процесса: av-dev-tasks, av-dev-git и будущий
плагин документов от OpenSpec не зависят и работают на python/ansible-проектах.
Причина: непроверенная ветка деградации хуже честной строки «требуется OpenSpec» — она даёт ложную уверенность, что проект без спек поедет.
B. Нормативный дом поведения — openspec/specs/. architecture.md
переопределяется как обзор: принципы, компоненты со ссылками на capability,
внешние форматы данных, раскладка, деплой, открытые вопросы. Поведения он не
описывает.
Причина: opsx:archive вливает дельты именно в openspec/specs/ — любой
другой нормативный дом обязан синхронизироваться руками и разойдётся. Форма
jellybit это уже подтвердила на 43 изменениях.
C. openspec/config.yaml → context держит только нужды генерации. Язык,
правила именования capability, придирки валидатора RFC 2119 — и ссылки. Правило
ревью, пересказ конвенций и инварианты оттуда вычищаются: у них есть свои дома.
Причина: блок «Ревью (процесс, не артефакт)» в обоих config.yaml дословно
повторяет шаги 4 и 7 task-pipeline. Это второй дом для правила, которым владеет
плагин, и он разойдётся на первой же правке.
Что из этого следует
Из A:
- Три места с веткой деградации переписываются на объявленную предпосылку плюс
проверку на старте (есть
openspec/, разрешаютсяopsx:*) и внятный отказ:task-pipelineпредпосылки,review-pipelineпредпосылки,task-batchпредпосылки. - Описание
av-dev-pipelineв маркетплейсе получает строку «требует OpenSpec». - Факт для темы «объединять ли tasks и pipeline»: объединение потянуло бы зависимость от OpenSpec на управление задачами, которой там сейчас нет.
Из B:
- Правило «поведение — в спеку, устройство и границы — в архитектуру» становится
контрактом плагина документов и правилом шага «синк документации» в
task-pipeline. - healthlog чистится не разом: раздел вычищается той задачей, которая его касается. Нужен способ не потерять остаток — иначе 950 строк «Хранилища» останутся навсегда.
- Дыра, которую решение открывает: «почему» после архивации. Сегодня
CLAUDE.mdhealthlog велит писать причину решения вarchitecture.md— а мы её оттуда выселяем. Спеки нормативны и «почему» не держат;design.mdживёт внутри change и уезжает в архив. Либо ADR (как у jellybit), либо явное правило «почему живёт в архивных change». Первый вопрос следующей темы.
Из C:
av-dev-pipelineдаёт образецopenspec/config.yamlотдельным reference — он владеет связью с OpenSpec. Заполняется при старте проекта и приadopt.- У обоих проектов из
config.yamlвычищается блок «Ревью (процесс, не артефакт)», пересказ конвенций и инвариантов.
2. Канон документов проекта (2026-08-03)
Что было
Измерено по обоим проектам:
- «Почему» не теряется — оно не находится.
design.mdпишется почти всегда (jellybit 39 из 43 архивных change, healthlog 9 из 9 — ≈285 КБ за две недели) и имеет секцииContext/Goals / Non-Goals/Decisions/Risks / Trade-offs, то есть является ADR по структуре. Против этого ADR руками: 6 записей у jellybit, четыре из них 13 июня — в день старта; между 15 июня и 23 июля прошло ~40 изменений и ноль ADR. У healthlog ADR нет вовсе, а настоящее ADR-рассуждение (отказ от DuckDB) лежит в разделе «Открытые вопросы» файлаarchitecture.md, потому что больше некуда. - Два плана.
docs/plan.mdhealthlog («порядок и его обоснование», 11 шагов) и<tasks>/PLAN.mdизav-dev-tasks(«линия целей с обоснованием порядка прозой») — один артефакт под двумя именами. - Дубли спек у jellybit. Из шести файлов
docs/specs/три (recognition,review-ux,workflow) описывают поведение, уже покрытое capability вopenspec/specs/. docs/drafts/раскладывается без остатка:roadmap.md→ линия целей,conventions-backlog.md→ задачи[idea],logical-title-model.md(293 строки, итог «сущностьtitleне вводим») → намеренный отказ, то есть ADR.
Решено
D. «Почему» — ADR как промоут поверх архива. Обоснование по-прежнему пишет
design.md; ADR — короткая запись, цитирующая решение и ссылающаяся на архивный
design.md. Заводит её шаг «синк документации» пайплайна по названному
триггеру (дорогой откат / намеренный отказ от очевидного / пересмотр прежнего
решения), а не человек по вдохновению.
Причина: ручной ритуал эмпирически не выжил — 6 записей на 52 изменения.
Автоматический (opsx:propose пишет design.md всегда) работает и производит на
порядок больше. Чинить надо не дом, а индекс и критерий промоута.
E. docs/plan.md растворяется в <tasks>/PLAN.md. Файл удаляется, 11 шагов
становятся линией целей, ссылки в CLAUDE.md и паспорте переводятся.
F. Пути жёсткие, оба проекта приводятся к одному виду. Плагин знает раскладку
поимённо; указателя вида .docs.json нет.
Причина (словами владельца): «так проще ориентироваться во множестве проектов,
а не видеть слегка похожую, но разную структуру в каждом. Все проекты малого и
среднего размера, проще подогнать их под одну структуру. Кроме того, у OpenSpec
тоже структура строгая». Цена принята сознательно: плагин перестаёт быть
переносимым на чужой репозиторий, а adopt из «поправь указатели» превращается в
«перенеси файлы».
G. Конвенции и разведка — каталогами с README-индексом. docs/conventions/
и docs/research/: путь жёсткий, нарезка внутри свободна. Схема хранилища —
отдельный docs/database.md (своя каденция: меняется миграцией, а не
архитектурным решением; гейт healthlog уже сверяет миграции с документацией).
Конвенции идентификаторов и именования — не схема, они в conventions/.
H. Слота для черновиков нет. Идея → задача [idea]; намеренный отказ → ADR;
порядок работ → PLAN.md; незрелое размышление → opsx:explore внутри change.
Канон
CLAUDE.md памятка агенту: что это, стек, инварианты, команды, слоты
docs/
passport.md зачем и для кого; чем НЕ является; сценарии; референсы
architecture.md как сложено — обзор: принципы, компоненты со ссылками
на capability, внешние границы, раскладка, деплой
database.md схема хранилища (там, где есть БД)
conventions/README.md + <тема>.md как пишем код; README держит правило промоута
research/README.md + <тема>.md что показала реальность: чужие форматы, живые данные
adr/README.md + template.md + ADR-*.md почему — промоут поверх архивных design.md
review-journal.md промахи конвейера ревью ← уточнено в теме 3
review-brief.md предмет ревью — см. тему 3 ← отменено в теме 3
tasks/ av-dev-tasks: items/, PLAN.md, BACKLOG.md, SPRINT.md, REJECTED.md
openspec/
config.yaml только нужды генерации + ссылки
specs/<capability>/spec.md что система делает — нормативно
changes/archive/ журнал изменений с design.md — сырьё для ADR
Слотов нет у: docs/drafts/, docs/specs/, docs/plan.md, BRIEF.md,
docs/backlog/, docs/review/journal.md.
Что из этого следует
- Переезд healthlog:
architecture.md1611 → обзор (поведение уезжает вopenspec/specsпо разделу за задачу);conventions.md→conventions/README.md;local-research.md1829 →research/;plan.md→docs/tasks/PLAN.md;backlog/→docs/tasks/; завестиdocs/adr/. - Переезд jellybit:
BRIEF.md→docs/passport.md(заодно обновить — не трогался с 13 июня);docs/specs/architecture.md→docs/architecture.md;docs/specs/database.md→docs/database.md;docs/specs/jellyfin-layout.md→docs/research/;docs/specs/{recognition,review-ux,workflow}.mdсверить с capability и удалить как дубли;docs/review/journal.md→docs/review-journal.md;drafts/растворить по H;docs/backlog/→docs/tasks/. adoptменяет природу — теперь он переносит файлы, а не правит указатели. Разбирается в теме про старт проекта.- Открыто до темы 6 (поддержание): точная формулировка триггера промоута в
ADR; нужен ли механический
checkраскладки документов, раз пути жёсткие; как не потерять остаток при постепенной чисткеarchitecture.md.
3. Брифа ревью нет — бриф это и есть канон (2026-08-03)
Что было
Контракт брифа — 413 строк, 13 разделов, отдельный файл docs/review-brief.md,
который каждый проход читает как истину. Заполнение на обоих проектах дало 841 и
734 строки, и REMAINING.md уже отметил, что часть разделов вырождается в
пересказ.
Разбор по разделам после решения F (жёсткие пути) показал: посредник между агентом и файлом не нужен, когда путь известен. Восемь из тринадцати разделов дублируют канон или снимаются жёсткими путями.
Решено
I. Отдельного файла-брифа нет. Проектную конкретику проходам дают документы
канона напрямую, по жёстким путям. Формулировка владельца: «артефакты в docs и
должны стать частями брифа, а для ревью достаточно дать ссылки на эти артефакты».
Причина: один факт — один дом. Бриф был вторым домом для паспорта, инвариантов и карты, а разошедшийся бриф хуже отсутствующего: он выглядит актуальным.
J. Заводится docs/security.md. Периметр первой строкой (целевой и
сегодняшний, если контур не развёрнут), недоверенный вход и его каналы, из чего
строятся пути и ключи, что разграничивает доступ, что чувствительнее чего, что
вне модели. Материал уже есть, но рассыпан: у healthlog — раздел
«Аутентификация» в architecture.md и строка про секреты в CLAUDE.md, у
jellybit — секреты в conventions/config.md. Периметра нет ни у одного, а
без него враждебный проход не выбирает между «открыт наружу» и «контур
доверенный».
K. review-journal.md → docs/review.md: журнал дефектов плюс настройка
конвейера под проект. Туда садится остаток брифа, который фактом о проекте не
является — типовые узлы, типовые ложноположительные, вопросы к проходам,
недоступно проверке.
Причина: все четыре — производные калибровки, и журнал им источник. ## Вопросы к проходам сам называет журнал главным источником; ### Перестали проверять сознательно требует ссылки на его запись.
L. Журнал расширяется до всех воспроизведённых дефектов с пометкой «проскочил / пойман ревью». Эвал-сет для калибровки — выборка по пометке.
Причина: пойманные дефекты с оракулом (768 МиБ пика, 5.019 с удержания блокировки) сегодня не сохраняются нигде, кроме отчётов триажа в архиве change, а они и есть лучшая опора для прохода — проектные, воспроизводимые, однажды оказавшиеся правдой.
M. Семантика гейта — в CLAUDE.md, расширением раздела «Команды». Чем
краснеет безусловно и почему, где логи, что означает исход, чего в гейте
намеренно нет, кто и когда обязан гонять дорогое вне гейта, что запускать
запрещено (с путями). Гейт краснеет не только в ревью — это факт о проекте.
N. Severity инвариантов дописывается в CLAUDE.md рядом с формулировкой.
Контракт брифа сам называл это лучшим исходом; жёсткие пути делают возможным.
Оговорка «выведена по обратимости» исчезает вместе с пересказом.
Канон после темы 3
CLAUDE.md что это, стек, инварианты с severity, команды,
семантика гейта, запреты, слоты
docs/
passport.md зачем и для кого; чем НЕ является; сценарии; референсы
architecture.md как сложено — обзор; окружение, внешние зависимости,
наблюдатель, характер потока
database.md схема хранилища; представление данных и настройки
с числовым значением (таймаут занятости, лимит тела,
режим журналирования, ретеншен)
security.md периметр первой строкой; недоверенный вход; из чего
строятся пути и ключи; разграничение; что вне модели
conventions/README.md + <тема>.md
research/README.md + <тема>.md наблюдения и измеренные числа с провенансом
adr/README.md + template.md + ADR-*.md
review.md настройка конвейера под проект + журнал дефектов
tasks/ av-dev-tasks
openspec/
config.yaml, specs/<capability>/spec.md, changes/archive/
Слотов нет у: docs/review-brief.md, docs/drafts/, docs/specs/,
docs/plan.md, BRIEF.md, docs/backlog/, docs/review-journal.md.
Что из этого следует
- Скилл
project-briefрастворяется. Заведение недостающих документов канона — часть скилла старта/адаптации (тема 5, требование Т1). - Девять charter'ов переписываются второй раз. Сейчас каждый читает «из
раздела
## Xбрифа»; станет — из файла канона. Цена названа вслух: первая переписка (вынос в плагин) осталась незамеренной —REMAINING.md, пункт 1. Вторая делает замер по четырём реальным находкам healthlog обязательным, а не желательным: два неизмеренных изменения подряд в том самом месте, где присваивается severity. - Теряется соседство фактов, и charter обязан сшивать. Контракт настаивал,
что замер становится находкой только рядом с настройкой: «768 МиБ пика» —
аномалия, лишь если известно, что запись лежит сжатой и распаковывается
целиком; «5.019 с удержания блокировки» — отказ соседа, лишь если известен
таймаут занятости. Теперь это
research/иdatabase.md, и charter'ыops,adversary,reimplобязаны прямо говорить «собери из этих двух», иначе проход снимет верное число и честно понизит находку до гипотезы. - Деградация становится поразрядной — и это лучше прежнего «нет брифа →
деградирует всё». Нет
security.md— деградируетadversary; нетresearch/— числа неизвестныops,adversaryиreimpl; нетpassport.md— архитектурный проход теряет границу домена. Каждый проход пишет свою строку в границы покрытия. - Открытый вопрос из
REMAINING.mdзакрыт: раздел## Триггерыудаляется вместе с брифом. Правило выбора профиля остаётся в скилле конвейера; проектная конкретизация, если понадобится, — вdocs/review.md.
4. Границы плагинов (2026-08-03)
Что было
Связь tasks ↔ pipeline уже сделана ролями, а не именами: скиллы говорят
«пайплайн проекта», «владелец спринта», «тот, кто ведёт задачи». Жёсткая ссылка
по имени ровно одна — task-pipeline:112 на канонический текст правила про
остаток внутри session, и рядом обработан случай «плагин не подключён».
Слоты CLAUDE.md при этом дублировались уже внутри одного плагина: шесть у
tasks, семь у session, три пары — одно и то же. Темы 2–3 растворили ещё
часть: «куда переезжает суть» отвечает канон, «оракулы» — семантика гейта
(решение M), «где живёт разбор процесса» — docs/review.md (решение K). Из
тринадцати остаётся около четырёх.
Решено
O. Три плагина: av-dev-pm, av-dev-pipeline, av-dev-git.
av-dev-pm(бывшийav-dev-tasks) — управление продуктом: канон документов, задачи, цели, спринты, старт и адаптация проекта. Владеет всемdocs/, включаяdocs/tasks/.av-dev-pipeline— исполнение: SDD-цикл, конвейер ревью, девять агентов.av-dev-git— стиль коммитов; работает в любом репозитории.
Причина (словами владельца): «пайплайн можно и переиспользовать в других
проектах с более простым подходом к управлению». Это подтверждается разбором:
пайплайн зависит от файлов канона и от OpenSpec, а не от плагина av-dev-pm.
В чужом проекте нужных файлов нет — включается поразрядная деградация (следствие
16), и это штатный режим, а не поломка.
Имя: pm = product management, «объединение всех операций по управлению
продуктом», и согласуется с av-dev-git.
P. Граница «пайплайн не закрывает задачу» снимается. Закрывает задачу и
двигает строки между SPRINT.md / BACKLOG.md / REJECTED.md агент-
оркестратор — task-pipeline и task-batch, а не сабагенты внутри них. Зовёт
он tasks.py через слот «Команда учёта задач» в CLAUDE.md.
Слот, следовательно, не исчезает, а становится мостом между плагинами — и заодно тем, чего в чужом проекте нет, отчего пайплайн там работает как прежде: докладывает исход, записей учёта не трогает.
Q. av-dev-backlog помечается устаревшим и остаётся до перевода jellybit.
Описание переписывается так, чтобы не ловить триггер «добавь задачу в беклог» —
иначе агент выбирает между ним и av-dev-pm случайно.
Что из этого следует
- Переименование
av-dev-tasks→av-dev-pmтянетplugin.json,marketplace.jsonи пространство имён скиллов:av-dev-tasks:session→av-dev-pm:session, включая ссылку изtask-pipeline:112. - Раздел «Стимулы, которые процесс создаёт» в
sessionпереписывается. Снятая граница выбила механическую опору у трёх защит: «сжать задачу до остатка», «занизить урожай», «занизить критерии приёмки» — во всех трёх приёмщик и исполнитель теперь совпадают. Остаются: отчёт триажа вopenspec/changes/<id>/review/(независимый артефакт,task-batchуже сверяет полноту ревью по нему, а не по прозе исполнителя),SPRINT.mdпод git с видимой историей иreopen <slug> --reason— закрытие не окончательно, приёмка человеком на сессии его отменяет. Раздел обязан назвать их поимённо, иначе обещает защиту, которой нет. - Конфликт владения
docs/tasks/снят — канон и задачи теперь в одном плагине. - Скилл
adoptизav-dev-tasksпоглощается скиллом адаптации проекта уровня канона (требование Т1). Разбирается в теме 5. - Состав
av-dev-pm:tasks,session(есть),docs— ведение канона,project— старт, adopt, check, upgrade (тема 5).
5. Старт проекта и жизненный цикл под каноном (2026-08-03)
Что было
Требование Т1: прийти в любой старый проект и перевести на текущие рельсы; канон сам меняется, значит уже приведённые проекты тоже повышаются.
Существующий adopt (уровень задач) даёт готовую форму: scan — только
чтение, карта → суждение человека → apply — запись одним проходом, с отказом
до первой записи при неверной карте и с обязательным разделом «не разложилось»
поимённо. Форма переносится на уровень канона как есть.
Четыре операции различаются не поровну: adopt, check и upgrade — одна
машина сравнения с разными исходами, а init — принципиально другой режим,
разговор, а не сверка.
Решено
R. Два скилла: av-dev-pm:init и av-dev-pm:canon. init — интервью по
входному брифу для нового проекта. canon — привести к канону: check, adopt,
upgrade одной машиной.
S. Скелет канона заводится целиком, незаполненное называется пустым. Все файлы канона есть с первого дня, но незаполненный держит одну честную информативную строку: «наблюдений на живых данных нет — внешний источник один, формат документирован», «прецедентов не накоплено», «внешних зависимостей нет, смотри на диск и на СУБД».
Причина: это тот же принцип, что был в контракте брифа, поднятый на уровень файлов. Проход читает такую строку как факт, а не как пробел, и не тратит обязательный вопрос впустую. Отсутствие файла он прочитать не может никак.
Защита от вырождения в заглушки берётся у tasks.py: пока на месте стоит
плейсхолдер шаблона, check о нём напоминает. Строка «TBD» — это не «пустое
названо пустым», и check обязан их различать.
T. Скрипт docs.py плюс версия канона в docs/.pm.json. Отдельный скрипт,
не расширение tasks.py: рефакторинг 2421 работающей строки ради удобства вызова
не окупается. docs.py check зовёт tasks.py check для своей части.
Граница механизируемого объявляется вслух — иначе check соврёт.
Проверяет docs.py |
Судит агент |
|---|---|
| отсутствующие пути канона | смысловой дубль (docs/specs/recognition.md против capability) |
файлы в docs/ вне канона |
поведение, оставшееся в architecture.md |
| битые относительные ссылки | протухший факт, разошедшийся с кодом |
| версия канона и её отставание | достаточность честной строки в пустом слоте |
| нетронутый плейсхолдер шаблона |
check, отчитавшийся «канон соблюдён» на проекте, где из шести файлов три
лишние, хуже отсутствующего.
Порядок интервью init — зависимость, а не удобство
Цель и потребители → чем это не является и мера успеха → периметр и что
недоверенное → стек, хранилище, необратимое → чем краснеет гейт → первые цели в
PLAN.md. Каждый блок опирается на ответ предыдущего.
Вход — свободный текст «что мне нужно и почему» (образец формы: BRIEF.md
jellybit, 6 КБ). После init его дом — passport.md; отдельным файлом он не
остаётся.
init физически не производит полный канон. В новом репозитории нет кода, а
architecture.md, database.md, conventions/ и research/ выводятся из него.
Они заводятся скелетом с честной строкой («архитектуры пока нет: кода нет,
заводится первой задачей») и наполняются шагом синка документации.
Что из этого следует
docs/.pm.jsonпоглощает<tasks>/.tasks.json. Меняется цепочка разрешения вtasks.py— сегодня он ищет.tasks.jsonвверх от текущего каталога. Нужен переходный период либо чтение обоих.tasks.py adoptстановится шагом внутриcanon adopt, а не отдельной пользовательской операцией:docs/tasks/— часть той же раскладки.- Версия канона — целое число, не semver: у канона нет обратной совместимости, есть только «приведён» и «не приведён».
- Журнал изменений канона живёт в плагине —
av-dev-pm/skills/canon/references/changelog.md, запись на версию: что добавилось, что переехало, что удалено, что сделать проекту. - Открыто до темы 6: звать ли
docs.py checkиз гейта проекта. У healthlogtask gateуже сверяет миграции с документацией, так что место есть; но гейт принадлежит проекту, и плагин может только рекомендовать строкой в отчёте.
6. Поддержание документов по ходу разработки (2026-08-03)
Что было
Гейт healthlog уже изобрёл нужный механизм для одного документа —
scripts/gate.py:177-181: миграция изменена, а docs/database.md нет → FAIL.
Документ канона сверяется с кодом красным гейтом, а не напоминанием.
Против этого — прямое доказательство, что́ не работает: у adr/ был список
триггеров прозой («выбор технологии, структурные решения, дорогой откат,
намеренный отказ»), и он дал 6 записей на 43 изменения. Прозаический триггер,
который некому проверить, не срабатывает.
Механизируемы три документа из десяти: database.md (миграция), architecture.md
(capability в openspec/specs/ без упоминания в обзоре), tasks/ (tasks.py check). Плюс openspec/specs/ вливает opsx:archive.
Решено
U. Принуждённое отрицание в докладе шага синка. Шаг обязан назвать каждый документ канона: обновлён — чем, либо «не требуется, потому что…». Нетронутые группируются одной строкой с общей причиной.
Причина: это тот же приём, что «границы покрытия» в отчёте ревью и «пустой пункт называется пустым» в каноне — и единственный, о котором в этом репозитории есть данные, что он работает. Умолчание «не написал» становится неотличимым от «написал, что не требуется», только если отрицание обязательно.
Триггер ADR, окончательная формулировка. Запись заводится, когда верно одно
из трёх: дорогой откат (переделка стоит дороже переписывания одного файла);
намеренный отказ от очевидного подхода; пересмотр прежнего решения — тогда
у старой записи обязателен статус «заменено на». Не заводится для рутины и для
того, что видно из кода и git log. Источник — архивный design.md: ADR его
цитирует и на него ссылается, а не пересказывает.
V. docs.py check обязателен в гейте проекта. Скилл canon при адаптации
добавляет шаг и печатает это в отчёте.
Причина: гейт — единственный общий станок, который нельзя пропустить. Проверка, которую зовёт агент, может быть не позвана; прецедент в самом healthlog уже есть.
Сверка «миграция изменена — database.md нет» обобщается: путь миграций
проекта записывается в docs/.pm.json рядом с версией канона, и docs.py делает
эту проверку сам, а не каждый проект заново.
W. Остаток чистки помечается маркером и считается числом. Неразобранный
раздел получает <!-- канон: поведение → openspec/specs/<capability> -->,
docs.py считает маркеры и печатает остаток. Закрывается порциями, как
переоценка задач.
Маркеры гейт не красят. Это долг, а не отказ: покрасневший гейт на первом маркере сделал бы постепенный переезд невозможным, а разовый — обязательным. Число печатается и убывает на глазах.
Что из этого следует
- Шаг 9
task-pipelineпереписывается из четырёх пунктов прозой в построчный доклад по документам канона. promote.md, шаг 3, переписывается: «вычеркнуть пункт из брифа, правило переезжает в перечень механизированного в разделе## Карта» → перечень механизированного живёт вconventions/README.md. Брифа нет.docs/.pm.jsonдержит не только версию канона, но и пути, нужные проверкам: каталог миграций — как минимум.docs.py checkполучает две сверки с кодом, а не только раскладку: миграции ↔database.md, capability ↔ упоминание вarchitecture.md.
7. Раскладка скиллов и доставка скриптов (2026-08-03)
Решено
X. Пять скиллов в av-dev-pm.
av-dev-pm/skills/
init/ интервью по брифу → канон нового проекта
canon/ раскладка: check / adopt / upgrade
docs/ содержимое канона: ADR из архивного design.md, промоут конвенций,
запись в research/ и review.md, чистка architecture.md
tasks/ формат и содержимое задач
session/ ритуал спринта
Причина отдельного docs: правила ведения содержимого канона обязаны жить у
владельца канона, а не в шаге синка чужого плагина — иначе проект без пайплайна
документацию вести не может. Это работает потому, что вызов скилла через
пространство имён между плагинами возможен, в отличие от
$CLAUDE_PLUGIN_ROOT: task-pipeline уже зовёт opsx:propose и
av-dev-pipeline:review-pipeline. Шаг синка зовёт av-dev-pm:docs, а в чужом
проекте деградирует до прозаического списка.
Симметрия, по которой резалось: раскладка и содержимое разделены и для
документов, и для задач — canon / docs, tasks / session.
Y. Скрипты не копируются — живут вместе со скиллами. Три вызывающих, три способа дотянуться:
| Кто зовёт | Как |
|---|---|
скиллы tasks, canon, docs |
$CLAUDE_PLUGIN_ROOT — свой плагин, работает всегда |
task-pipeline, task-batch |
вызов скилла av-dev-pm:tasks, а не путь |
| гейт проекта | путь переменной с умолчанием на канонический путь маркетплейса; пишет canon adopt, внятный красный отказ, если не найден |
Слот «Команда учёта задач» всё равно исчезает — но снимает его не копия, а
вызов скилла через пространство имён. Тот же приём, которым шаг синка зовёт
av-dev-pm:docs (решение X): чужой плагин зовёт скилл, скилл разрешает свой
$CLAUDE_PLUGIN_ROOT сам. Путь наружу не выносится вовсе.
Первоначально здесь было решено вендорить scripts/tasks.py и
scripts/docs.py в проект. Отменено после проверки фактов:
- CI нет ни в одном проекте (ни
.github, ни woodpecker, ни drone). Pre-commit есть только у jellybit —lefthookс gofmt/vet/lint/test/gitleaks — и гоняется на той же машине, где установлен плагин. Довод «не работает в CI и у человека без Claude Code» оказался гипотетическим. - Пара «источник — копия» существует и без вендоринга. Установленный
маркетплейс — git-клон; на момент разбора он стоял на
092d07c, на четыре коммита позадиmaster, иav-dev-tasksсav-dev-pipelineв нём отсутствовали вовсе. Довод «вендоринг создаёт вторую копию» был слабее, чем подан. - Обновление маркетплейса — одна точка на все проекты. При вендоринге каждый проект повышается отдельно, и проекты расходятся друг с другом — ровно та разнородность, против которой принято решение F.
Z. Имени у процесса нет — процесс это av-dev. Маркетплейс уже
av-dev-skills, плагины av-dev-*; в CLAUDE.md проекта пишется «процесс
av-dev, канон версии N». Имя, которое нигде не работает, — украшение.
Что из этого следует
- Решение P уточняется: оркестратор закрывает задачи вызовом скилла
av-dev-pm:tasks, а не запуском скрипта по пути. Плагина в проекте нет — вызов не разрешается, и пайплайн, как прежде, только докладывает исход. - Слот исчезает из двух скиллов —
tasks(слот 6) иsession(слот 7), — и из текстовtask-pipelineиtask-batch, которые на него ссылаются. canon upgradeотвечает за раскладку и версию вdocs/.pm.json. Скрипты обновляются обновлением маркетплейса, а не проектом.- Скрипты живут в
av-dev-pm/skills/{tasks,canon}/scripts/.docs.py— вcanon, потому что раскладку проверяет он. canon checkсверяет версию канона проекта с версией установленного плагина и говорит, кто отстал. Это нужно и без вендоринга: маркетплейс — git-клон, обновляется явно, и на момент разбора отставал на четыре коммита.- Установленный маркетплейс требует обновления перед любой работой —
сейчас в нём нет ни
av-dev-tasks, ниav-dev-pipeline. Это первый шаг выката (тема 8), иначе проверять будет нечего.
8. Порядок выката (2026-08-03)
Объём
Ссылок на бриф — 168 строк в 19 файлах av-dev-pipeline, из них ~48 уходят
вместе с удаляемыми project-brief/SKILL.md, references/project-brief.md и
references/brief-template.md. Остальное переписывается на пути канона.
Решено
AA. Инструмент строится целиком, потом проверяется. Не пилот руками.
Риск принят сознательно: если замер покажет деградацию severity, чинить придётся канон, зашитый к тому моменту в три скилла, скрипт и мигрированные файлы healthlog.
Удешевление, которое обязано быть заложено сразу: определение канона живёт в
единственном reference-файле, который читают init, canon и docs, а не
повторяется в каждом. Правка канона — одно место плюс запись в журнал версий.
Страховка порядка: замер ставится перед переездом jellybit, а не после всего, — он всё ещё блокирует то, что дороже всего откатывать.
BB. Работа ведётся в docs/tasks/ самого dev-skills. Скилл tasks не
требует ни OpenSpec, ни языка — задачи для него просто каталог markdown. Цели —
крупные куски, задачи — следствия. Заодно первая боевая обкатка собственного
инструмента.
CC. AGENTIC-TASKS.md сжимается до истории решений и переезжает в
dev-skills отдельным HISTORY.md: почему не Scrum, числа первого замера, что
отвергнуто и почему. Он описывает процесс, а процесс живёт здесь, не в healthlog.
Остальное содержимое уже в плагинах, и второй дом для тех же правил — ровно то,
против чего документ сам и написан.
Порядок
0. обновить установленный маркетплейс предусловие всего
0.5 завести docs/tasks в dev-skills, разложить 37 следствий по целям
1. РЕПОЗИТОРИЙ ПЛАГИНОВ
1.1 av-dev-tasks → av-dev-pm, пространство имён
1.2 канон одним reference-файлом — единственный дом определения
1.3 правки tasks и session: слоты, «Стимулы», .pm.json
1.4 новые init, canon, docs + docs.py
1.5 av-dev-pipeline: удалить project-brief, снять ветки деградации OpenSpec,
переписать шаг 9, девять charter'ов, promote.md, убрать слот
1.6 av-dev-backlog устаревшим; README; журнал канона v1; HISTORY.md
1.7 REMAINING.md пересобрать — часть его вопросов закрыта этим разбором
2. HEALTHLOG — первая боевая проверка инструмента
canon adopt, заполнение канона, security.md, review.md, ADR,
маркеры в architecture.md, docs.py check в гейте
3. КАЛИБРОВКА на четырёх находках healthlog БЛОКИРУЕТ шаг 5
4. один-два спринта healthlog на новом процессе
5. JELLYBIT — переезд, удаление дублей specs, растворение drafts
Что из этого следует
REMAINING.mdчастично устарел: пункт 2 «Завести брифы» отменён темой 3; закрыты открытые вопросы про## Триггеры,av-dev-backlog, имя процесса иAGENTIC-TASKS.md. Пункт 1 (калибровка) стал обязательным, а не желательным. Пересобрать на шаге 1.7.- Замер — единственный шаг, который нельзя переставить. Всё остальное в порядке 1–5 можно тасовать; шаг 3 стоит перед шагом 5 жёстко.