Files
dev-skills/av-dev-pm/skills/canon/references/skeletons.md
T
avandClaude Opus 5 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>
2026-08-05 15:35:06 +03:00

19 KiB
Raw Blame History

Скелеты документов канона

Что кладут init и canon adopt в незаполненный слот. Правило одно: честная информативная строка вместо заглушки. Проход читает строку как факт; <!-- заполнить: … --> он читает как пробел, и docs.py check о таком плейсхолдере напоминает.

Плейсхолдер ставится только там, где ответ обязан быть и его не спросили. Всё, чего в проекте пока просто нет, описывается словами, а не плейсхолдером.

Шаблоны — единственное место, где правило канона копируется намеренно. adr/README.md и review.md уезжают в репозиторий проекта и обязаны там что-то говорить; определение при этом остаётся в canon.md. Отсюда обязанность: правка такого правила в каноне тянет запись в changelog.md — и запись называет, какой файл проекта поднимает upgrade. Без этого копия в проекте останется на старой версии молча.

Каждая такая копия помечена и сверяется машиной. Дом обрамляется <!-- дом: <id> --><!-- /дом: <id> -->, копия — <!-- копия: <id> из <путь> --><!-- /копия: <id> -->; scripts/copies.py маркетплейса требует дословного совпадения. Комментарии невидимы в отрендеренном markdown и уезжают в проект вместе со скелетом — там они говорят читателю, что у текста есть дом. Правишь текст внутри маркеров — правь дом, а не копию.

docs/passport.md

# Паспорт проекта

Зачем это и для кого. [architecture.md](architecture.md) отвечает «как
устроено», [tasks/ROADMAP.md](tasks/ROADMAP.md) — «в каком порядке», паспорт —
«зачем и для кого».

## Цель

<!-- заполнить: одна фраза без технических деталей -->

**Потребители** — список закрытый: он определяет, что считать нужным, а что
интересным.

| Кто | Что ему нужно от нас |
| --- | --- |

Цель достигнута, когда:

## Что целью не является

Граница домена. По ней архитектурный проход судит, не перенесено ли понятие
через границу.

## Типовые сценарии

## Референсы

Где смотреть prior art, когда упёрлись.

docs/architecture.md

# Архитектура

Обзор: как сложено и где что работает. **Поведение системы здесь не
описывается** — его нормативный дом `openspec/specs/`.

## Принципы

## Компоненты

Каждый — строкой со ссылкой на capability, а не пересказом её требований.

## Внешние границы и форматы

## Эксплуатация

- Где работает, что рядом, кто перезапускает:
- Внешние зависимости поимённо и чем каждая отказывает (падает, отвечает
  медленно, молчит, отдаёт мусор):
- Кто заметит отказ и когда:
- Характер потока (непрерывный, по запросу, по расписанию):

## Единые точки проекта

Где генерируются идентификаторы и время; где единственный парсер входного
формата; где маппинг доменной ошибки в код ответа; где общий путь приёма.
Материал для вопроса «не появился ли второй способ делать то, что уже делается».

## Деплой

## Открытые вопросы

Пустой проект: «Архитектуры пока нет: кода нет. Наполняется первой задачей.» Нет внешних зависимостей: «Внешних зависимостей нет — смотри на диск и на СУБД.»

docs/database.md

# Схема хранилища

СУБД, миграции, правило времени и идентификаторов.

## Таблицы

## Представление данных

Чем физически лежит запись и что происходит при чтении и записи.

## Настройки с числовым значением

Таймаут занятости, режим журналирования, лимит тела, размер пула, ретеншен.
Без них замер не превращается в находку: пик памяти — аномалия только рядом
со строкой «запись лежит сжатой и распаковывается целиком».

Нет БД — файла нет, и в docs/.pm.json нет ключа migrations.

docs/security.md

# Модель угроз

## Периметр

<!-- заполнить: первой строкой, против кого защищаемся -->

Контур не развёрнут — назови оба периметра, целевой и сегодняшний, и скажи
прямо, против какого строятся находки.

## Недоверенный вход

Что приходит извне и каким каналом: тело запроса, файл, аргумент команды,
ответ внешней системы, содержимое архива.

## Из чего строятся пути и ключи

Раскладка файлов на диске, состав координатного ключа записи, имя каталога.
Отсюда строится выход за пределы песочницы.

## Что разграничивает доступ

## Что чувствительнее чего

## Что вне модели

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

docs/conventions/README.md

# Конвенции кода

Как мы пишем код — в отличие от `openspec/specs/`, который описывает, что
система делает.

**Прозой остаётся только то, что не выражается правилом.** Свойство, ставшее
правилом линтера, отсюда удаляется и переезжает в перечень ниже.

## Записи

## Механизировано

| Правило | Где механизировано |
| --- | --- |

Не названное здесь место механизации означает, что проход по конвенциям будет
добросовестно проверять уже проверенное.

Пустой проект: «Конвенций пока нет: код не написан. Наполняется по мере реального трения, а не вперёд.»

docs/research/README.md

# Разведка

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

**Каждый вывод — с числами и командой, которой получен**, чтобы его можно было
перепроверить.

## Как снималось

## Записи

Нет внешних источников: «Внешних источников данных нет — разведка неприменима.»

docs/adr/README.md

# Журнал решений

Одна запись — одно решение. **ADR это промоут поверх архивного `design.md`**,
а не второе сочинение: запись цитирует решение и ссылается на
`openspec/changes/archive/<id>/design.md`.

## Когда заводить

Верно одно из трёх:

<!-- копия: adr-когда-заводить из av-dev-pm/skills/canon/references/canon.md -->
- **дорогой откат** — переделка стоит дороже переписывания одного файла;
- **намеренный отказ** от очевидного подхода;
- **пересмотр прежнего решения** — тогда у старой записи обязателен статус
  «заменено на».
<!-- /копия: adr-когда-заводить -->

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

## Соглашения

- Имя файла — `ADR-ГГГГ-ММ-ДД-slug.md`, дата — когда решение реально принято.
  Слаг **английский по сути, а не транслитом**: `queue-as-table`, не
  `ochered-tablicej`. Форму имени и слаг проверяет `docs.py check`.
- Записи неизменяемы: передумали — новая запись, старой ставится статус.
- Активная запись статуса не имеет. Значений два: `заменено на ADR-…` и
  `устарело`; ставятся полем меты записи — `- **Статус:** …` рядом с датой и
  источником, а не абзацем в теле.

## Записи

Новые сверху.

| Дата | Запись | Статус |
| --- | --- | --- |

docs/adr/template.md

# Краткий заголовок решения

- **Дата:** ГГГГ-ММ-ДД
- **Источник:** openspec/changes/archive/<id>/design.md

Статус ставится тем же полем и только при пересмотре:
`- **Статус:** заменено на ADR-…` либо `- **Статус:** устарело`.
У активной записи поля нет.

## Решение

Что именно решено — одной фразой.

## Почему

Намерение и причина. Цитата из источника, а не пересказ. Пиши так, чтобы через
год было понятно без чтения переписки.

## Последствия

- `+` что стало лучше.
- `` чем платим: ограничения, риски, нагрузка на поддержку.

docs/review.md

# Ревью: настройка и журнал

## Как настроен конвейер

### Типовые узлы

Рода узлов проекта и 3–5 проверяемых свойств к каждому. Рода, а не инвентарь
пакетов: род, который проект задумал, но ещё не написал, включать полезно.

### Типовые ложноположительные

Находки, которые здесь выглядят убедительно и всегда неверны. Каждая — с одной
строкой «почему здесь это не дефект».

### Вопросы к проходам

Форма: `<имя прохода>: <вопрос> (<провенанс>)`. Главный источник — журнал ниже.
Проход, увидев свой блок, задаёт эти вопросы дополнительно к обязательным.

### Триггеры профиля

Проектная конкретизация правила выбора профиля: что здесь считается **новым
понятием или структурной единицей** (поднимает прогон до `wide` и запускает
архитектурный проход) и **где живут правила идентичности, слияния и разбора**
(до `deep`, запускает независимую реализацию) — перечнем узлов или capability,
поимённо. Уточняет умолчания конвейера, не отменяет их; рабочее умолчание —
`standard`.

Перечень для `deep` **производен от теста конвейера**, а не заменяет его:
правило попадает в класс, когда вариантов несколько, спека между ними не
выбирает, а неверный выбор не падает, а молча меняет смысл данных. Перечисляй
места, где этот класс здесь живёт, а не переписывай определение. Таких мест нет
вовсе — так и напиши: `deep` тогда не запускается никогда, и это законное
состояние.

### Недоступно проверке

**Не проверит ни один проход** — принципиальная граница; по факту промаха не
пересматривается.

**Перестали проверять сознательно** — что, когда и почему, со ссылкой на запись
журнала. Пересматривается **первым**, как только что-то проскочило.

## Журнал дефектов

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

Форма:

<!-- копия: журнал-дефектов-форма из av-dev-pipeline/skills/review-pipeline/references/review-journal.md -->
## ГГГГ-ММ-ДД — <краткое последствие> [проскочил|пойман]

- **Где:** путь:строка либо «конвейер, а не код»
- **Симптом:** как обнаружилось, кем и когда
- **Причина:** что на самом деле было не так
- **Чем воспроизведён:** тест, команда, замер — с числами
- **Почему не поймали:** только для проскочивших — какой проход обязан был найти
  и что ему помешало
- **Что меняем:** правило прохода, шаг гейта, конвенция, факт в документе
  проекта — либо «ничего, цена поимки выше цены дефекта»
<!-- /копия: журнал-дефектов-форма -->

Новый проект: «Дефектов пока не было. Настройка конвейера появится с первым ревью.»

CLAUDE.md

Лежит в корне, не в docs/. Единственный файл канона, который агент читает всегда, поэтому в нём то, без чего нельзя сделать ни шага.

# CLAUDE.md

Памятка для работы над <проект>. Перед задачей прочитай также
[docs/passport.md](docs/passport.md), [docs/architecture.md](docs/architecture.md)
и [docs/conventions/](docs/conventions/README.md).

## Что это

Абзац: что делает и чего **не** делает.

## Стек

## Инварианты

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

## Команды

## Гейт

- Команда целиком и как определяется база диффа:
- Где логи шагов:
- Что означает каждый исход:
- **Что красит безусловно и почему:**
- Чего в гейте намеренно нет и **кто тогда обязан это гонять:**

## Запреты

Что запускать нельзя, **с путями**: рабочая БД, боевой каталог данных, внешние
сервисы. Плюс где `testdata` и куда писать временное.

## Работа

- **Основная ветка:** <имя>
- **Необратимое** (спрашивается у человека всегда):
- **Общий станок** — какая проверка, покраснев, врывается в замороженный спринт:
- **Ориентир по размеру спринта:** 5–8 задач, ориентир а не закон
- **Что такое «сделана»:** пайплайн проекта пройден + критерии приёмки проверены
  поимённо

## Язык

- Документация, комментарии, сообщения коммитов — русский.
- Код и идентификаторы — английский.

Имя основной ветки, запреты с путями и «что необратимо» — не украшение: без первого падают git-операции батча и расчёт базы диффа, без второго проход может тронуть рабочие данные, без третьего вся шкала ранжирования триажа держится на догадке.

docs/.pm.json

{
  "canon": 4
}

Плюс "migrations": "<путь>", если есть БД. Ключ "tasks" заводится только когда имя файла или заголовка отличается от умолчания ({"backlog": "INDEX.md"}); секций беклога в нём нет — их дом заголовки ## индекса. Состав ключей — canon.md.