Files
dev-skills/av-dev-pm/skills/canon/references/canon.md
T
av 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,
  слот «Команда учёта задач» убран в пользу вызова скилла, раздел «Стимулы»
  переписан под совпавших приёмщика и исполнителя
2026-08-03 14:14:04 +03:00

19 KiB
Raw Blame History

Канон документов проекта

Версия 1.

Это единственный дом определения канона. Скиллы init, canon и docs читают его, а не пересказывают: три описания одной раскладки разъедутся, и работать будет то, которое прочитали последним. Меняется канон — меняется этот файл и появляется запись в changelog.md.

Зачем канон жёсткий

Пути фиксированы, и проект под них подгоняется, а не наоборот. Причина не техническая: проектов много, все малого и среднего размера, и ориентироваться в слегка похожих, но разных раскладках дороже, чем один раз привести их к общей. Рядом лежит OpenSpec, у которого структура тоже строгая.

Цена принята сознательно: плагин не переносится на чужой репозиторий как есть — чужой репозиторий приводится к канону скиллом canon.

Раскладка

CLAUDE.md                      памятка агенту: что это, стек, инварианты с
                               severity, команды, семантика гейта, запреты
docs/
  .pm.json                     версия канона и пути, нужные проверкам
  passport.md                  зачем и для кого; чем НЕ является; сценарии
  architecture.md              как сложено — обзор; окружение и эксплуатация
  database.md                  схема хранилища; представление данных и настройки
  security.md                  периметр; недоверенный вход; что вне модели
  conventions/
    README.md                  индекс, правило промоута, что механизировано
    <тема>.md
  research/
    README.md                  как снималось, индекс
    <тема>.md                  наблюдения и числа с провенансом
  adr/
    README.md                  индекс записей, статусы, правило замены
    template.md
    ADR-ГГГГ-ММ-ДД-slug.md
  review.md                    настройка конвейера под проект + журнал дефектов
  tasks/                       скилл tasks: items/, PLAN.md, BACKLOG.md,
                               SPRINT.md, REJECTED.md
openspec/
  config.yaml                  только нужды генерации артефактов + ссылки
  specs/<capability>/spec.md   что система делает — нормативно
  changes/archive/             архив изменений с design.md — сырьё для ADR

Текст документов — русский; слаги файлов, capability и задач — английские, kebab-case.

Роли документов

Одна строка на каждый — на какой вопрос он отвечает и кто его читает.

Документ Вопрос Кто читает, кроме человека
CLAUDE.md что нельзя нарушать, чем краснеет гейт все агенты, всегда
passport.md зачем и для кого, чем это не является architecture, rubric, reimpl, specs
architecture.md как сложено и где что работает все проходы ревью
database.md что лежит в хранилище и какими настройками ops, adversary, reimpl
security.md против кого защищаемся и что вне модели adversary
conventions/ как мы пишем код code
research/ что показала реальность, а не документация specs, reimpl, ops
adr/ почему решено именно так architecture
review.md как настроен конвейер и что уже проскакивало triage, каждый проход — свою часть
openspec/specs/ что система делает — нормативно specs

passport.md

Цель; закрытый список потребителей и что каждому нужно; чем целью не является — это граница домена, по которой архитектурный проход судит о переносе понятия; типовые сценарии; мера, по которой проект считается удавшимся; референсы, у кого подсматривать.

architecture.mdобзор, не поведение

Принципы; компоненты со ссылками на capability, а не с пересказом их требований; внешние границы и форматы чужих систем; окружение — где работает, что рядом, кто перезапускает; внешние зависимости поимённо и чем каждая отказывает (не только «падает», но и «отвечает медленно», «молчит», «отдаёт мусор»); кто заметит отказ и когда; характер потока — непрерывный, по запросу, по расписанию; что обратимо, а что нет; деплой; открытые вопросы.

Поведение системы сюда не пишется. Его нормативный дом — openspec/specs/, куда opsx:archive вливает дельты; второй дом синхронизировать руками невозможно, и он разойдётся.

Раздел, ещё не разнесённый при переезде, помечается маркером долга:

<!-- канон: поведение → openspec/specs/<capability> -->

docs.py считает маркеры и печатает остаток числом. Гейт от них не краснеет: это долг, а не отказ, иначе постепенный переезд стал бы невозможен.

database.md

Схема: таблицы, ключи, связи, правило времени и идентификаторов. Плюс то, чего нет в схеме, но без чего замер не превращается в находку: чем физически лежит запись (сжатый BLOB, JSON-строка, колонки), что происходит при чтении и записи (распаковка целиком, read-modify-write), и настройки с числовым значением — таймаут занятости, режим журналирования, лимит тела, размер пула, ретеншен.

Конвенции идентификаторов и именования — не схема, они в conventions/.

security.md

Периметр первой строкой. «Сервис открыт наружу» и «контур доверенный, публичного интернета здесь нет, не выдумывай его» — противоположные постановки под одним заголовком, и враждебный проход между ними сам не выберет. Контур ещё не развёрнут — назови оба периметра, целевой и сегодняшний, и скажи прямо, против какого строятся находки.

Дальше: что недоверенное и каким каналом приходит; из чего строятся пути и ключи (раскладка файлов, состав координатного ключа, имя каталога) — отсюда строится выход за пределы песочницы; что разграничивает доступ; что чувствительнее чего; что вне модели — перечислить явно.

conventions/

Прозой остаётся только то, что не выражается правилом. README.md держит индекс, правило промоута и перечень уже механизированного со ссылкой на место механизации — конфиг линтера, собственный анализатор, тест-сканер исходников. Непойманное место механизации означает, что проход добросовестно проверит уже проверенное.

research/

Наблюдения за внешним миром: что реально шлёт источник, чем документация формата расходится с практикой, какие числа сняты с живого потока. Числа — с провенансом, то есть с командой или условиями, которыми получены. README.md — как снималось и индекс тем.

Число без источника проход обязан читать как условие, а не как замер. Число, чей источник по ссылке не подтвердился, не выбрасывается и не переписывается по догадке — остаётся с пометкой «расходится с источником: там <что нашли>».

adr/

ADR — промоут поверх архивных design.md, а не второе сочинение. Запись цитирует решение и ссылается на openspec/changes/archive/<id>/design.md.

Заводится, когда верно одно из трёх:

  • дорогой откат — переделка стоит дороже переписывания одного файла;
  • намеренный отказ от очевидного подхода;
  • пересмотр прежнего решения — тогда у старой записи обязателен статус «заменено на».

Не заводится для рутины и для того, что видно из кода и git log.

Записи неизменяемы: передумали — заводится новая, старая получает статус. Активная запись статуса не имеет.

review.md

Два раздела с разными сроками жизни.

Настройка конвейера под проект: типовые узлы (рода узлов и 3–5 проверяемых свойств к каждому); типовые ложноположительные — находки, которые здесь выглядят убедительно и всегда неверны; вопросы к проходам поимённо с провенансом; недоступно проверке — два подраздела, «не проверит ни один проход» (принципиальная граница, по факту промаха не пересматривается) и «перестали проверять сознательно» (пересматривается первым).

Журнал дефектов: запись на каждый воспроизведённый дефект с пометкой проскочил / пойман ревью. Проскочившие — эвал-сет для калибровки конвейера, выборка по пометке. Пойманные с оракулом — лучшая опора для прохода: проектные, воспроизводимые, однажды оказавшиеся правдой.

CLAUDE.md

Что это и стек; инварианты с severity рядом с формулировкой — по ним проходы присваивают critical, поэтому severity стоит здесь, а не выводится каждым проходом заново; команды; семантика гейта — чем краснеет безусловно и почему, где логи, что означает исход, чего в гейте намеренно нет, кто и когда обязан гонять дорогое вне гейта; что запускать запрещено, с путями; что считается необратимым; общий станок, врывающийся в замороженный спринт; ориентир по размеру спринта.

openspec/config.yaml

Только нужды генерации артефактов — язык, правила именования capability, придирки валидатора RFC 2119 — плюс ссылки на документы канона. Правило ревью, пересказ конвенций и инварианты сюда не пишутся: у них есть свои дома, и второй дом разойдётся на первой же правке.

Правило единственного дома

Факт живёт ровно в одном файле; остальные ссылаются. Карта на случай спора:

Факт Дом
поведение системы openspec/specs/<capability>/spec.md
почему решено так adr/, источник — архивный design.md
граница домена, «чем не является» passport.md
инвариант и его severity CLAUDE.md
порядок работ и его обоснование docs/tasks/PLAN.md
измеренное число research/
настройка с числовым значением database.md
периметр и модель угроз security.md
что уже механизировано правилом conventions/README.md

Пустое называется пустым

Скелет канона заводится целиком с первого дня. Незаполненный документ держит одну честную информативную строку, а не заглушку:

  • «внешних зависимостей нет — смотри на диск и на СУБД»;
  • «наблюдений на живых данных нет: внешний источник один, формат документирован»;
  • «прецедентов не накоплено»;
  • «сознательно ничего не отключали»;
  • «архитектуры пока нет: кода нет, заводится первой задачей».

Проход читает такую строку как факт и не тратит на неё обязательный вопрос. Отсутствие файла он не может прочитать никак, а «TBD» читает как пробел — поэтому docs.py check отличает честную строку от нетронутого плейсхолдера шаблона и напоминает о втором.

Слотов нет

Файлы и каталоги, которых в каноне нет, и куда уезжает их содержимое:

Было Куда
docs/review-brief.md документы канона и есть бриф; остаток — в review.md
docs/specs/ openspec/specs/ (поведение) и architecture.md (обзор)
docs/drafts/ идея → задача [idea]; отказ → ADR; порядок → PLAN.md; размышление → opsx:explore
docs/plan.md docs/tasks/PLAN.md
BRIEF.md passport.md
docs/backlog/ docs/tasks/
docs/review-journal.md, docs/review/journal.md docs/review.md

Что проверяет машина, а что человек

Граница объявляется вслух в каждом отчёте: check, отчитавшийся «канон соблюдён» на проекте, где из шести файлов три лишние, хуже отсутствующего.

Проверяет docs.py Судит агент
отсутствующие пути канона смысловой дубль документа и capability
файлы в docs/ вне канона поведение, оставшееся в architecture.md
битые относительные ссылки протухший факт, разошедшийся с кодом
версия канона и её отставание достаточность честной строки в пустом слоте
нетронутый плейсхолдер шаблона связность и читаемость
маркеры долга — числом
миграция изменена, а database.md нет
capability без упоминания в architecture.md

docs/.pm.json

{
  "canon": 1,
  "migrations": "internal/store/migrations",
  "tasks": {
    "sections": ["ядро", "инфра"]
  }
}

canon — версия канона, под которую проект приведён, целым числом: обратной совместимости у канона нет, есть «приведён» и «не приведён». migrations — путь каталога миграций, если БД есть; по нему docs.py делает сверку с database.md. tasks — настройки каталога задач, переехавшие сюда из прежнего <tasks>/.tasks.json: один конфиг на весь канон, а не по одному на каталог.

Ключей будет больше по мере роста проверок; неизвестный ключ docs.py игнорирует, отсутствующий — считает «проверка неприменима» и говорит об этом строкой, а не молчит.