Files
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

308 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Журнал версий канона
Одна запись на версию. Проект знает свою версию из `docs/.pm.json`; `canon
upgrade` идёт по записям снизу вверх от версии проекта до текущей и делает то,
что в них названо.
Правило записи: **что добавилось, что переехало, что удалено, что сделать
проекту**. Без последнего пункта запись бесполезна — по ней и работает
`upgrade`.
Версия — целое число. Обратной совместимости у канона нет: есть «приведён» и «не
приведён».
---
## Версия 4 — 2026-08-05
Две правки, обе про то, как читается каталог задач. Первая — секция роадмапа
переименована, и вместе с именем расширен её смысл; достигнутое переехало вниз.
Вторая — **у каждой записи появился тип, и тип определяет, что с записью можно
делать**. Раскладка не меняется, файлов канона не прибавляется.
**Что переехало:**
- секция роадмапа `Разработка`**`Сопровождение`** (англ. `Tooling`
**`Operations`**). Прежнее имя называло слишком много: роадмап **весь** про
разработку, и секция с таким именем не отличалась от остальных ничем;
- **тип записи** — из префикса заголовка (`[goal]`/`[idea]`) и тега
`kind:<род>` в **поле меты `Тип`** первой строкой. Эмодзи в заголовке от него
производна;
- **поле места** у задачи: `Секция`**`Категория`**. У цели остаётся `Секция`:
у задачи поле называет полку домена, в которую она вернётся из спринта, у цели
— часть роадмапа, то есть состояние очереди. Одно имя на два смысла их и
смешивало.
**Что добавилось:**
1. **Смысл секции расширен.** Было «инструмент и процесс», стало «чем держат
проект: инструмент, процесс, эксплуатация». Метрики, логи, инфраструктура,
выкладка и дежурство — сюда же. Расширение не косметическое: английское
`Operations` при узком смысле обещало бы эксплуатацию, а внутри лежал бы
линтер.
2. **Общий словарь трёх мест** — [canon.md](canon.md), раздел «Сопровождение и
эксплуатация». Сопровождение — всё, чем держат проект; эксплуатация — его
часть, работа системы на проде. `ROADMAP.md`, секция `Сопровождение` — план
работ; `architecture.md`, раздел «Эксплуатация» — как устроено сейчас;
эксплуатационный проход ревью — оптика проверки. Слить их в одно слово
нельзя: они отвечают на разные вопросы. Слово **«поддержка» не употребляется
вовсе** — в нём слышится помощь пользователю.
3. **Граница с возможностями проходит по тому, кто наблюдает.** «Приложение
сообщает о своём состоянии» — возможность приложения, её место среди прочих
целей. «Дежурный видит состояние на одном экране» — сопровождение. Одни и те
же метрики попадают в разные секции роадмапа, и это верно.
4. **Порядок секций стал каноническим**, и `Готово` переехало **вниз**:
`Запланировано` | `Направления` | `Сопровождение` | `Готово`. Достигнутое
копится — через год этой секции больше, чем всех остальных вместе, — и стоя
первой она отодвигает за экран то, ради чего роадмап открывают чаще всего.
Порядок проверяет `tasks.py check`, переставляет `check --fix`.
5. **Заголовок секции отбивается пустой строкой с обеих сторон.** Прежде
проверялась только строка после заголовка; перестановка секций двигает целые
блоки, и два заголовка оказываются вплотную. Правит `check --fix`.
6. **Тип — единственная ось записи, закрытый словарь из пяти значений:**
`goal` | `feature` | `fix` | `chore` | `research`. Осей было две — тип записи
(`goal`/`idea`/`task`) и род работы (`kind:` тегом), — но из двенадцати
клеток произведения законны были шесть, а алгоритм работы крепится к роду, а
не к типу. Оси схлопнуты.
7. **Тип задаёт схему тела:** какие разделы обязательны, какие допустимы, нужна
ли цель, берётся ли запись в спринт. Проверяет `sprint take`, замечания даёт
`check`. Два раздела новые: **`Воспроизведение`** у `fix` (не
воспроизводится — это `research`, а не `fix`; правило было записано и не
проверялось) и **`Вопрос` + `Куда ляжет ответ`** у `research` вместо
критериев приёмки (приёмка разведки — записанный ответ, и критерии в форме
«оракул: тест» ей натянуты).
8. **Тип `idea` упразднён.** Он значил не род работы, а состояние
незаполненности, а состояние типом быть не может. Теперь оно называется
честно: `research` без раздела «Вопрос» — **сырьё**. В спринт не берётся, как
и прежняя идея, лежит **в конце своей категории** (проверяет `check`,
переставляет `--fix`) и отбирается `list --raw`. Порядка «по важности» в
беклоге по-прежнему нет: этот порядок производен от типа, а не назначен
человеком.
9. **Алгоритм работы над каждым типом** — отдельным файлом,
`skills/tasks/references/task-<тип>.md`: схема, что проверяет машина, что
человек, и порядок шагов.
10. **Имена файлов проверяются.** Правило «текст русский, имена английские»
стояло в каноне и не было подкреплено ничем: `docs.py` имён не смотрел вовсе.
Теперь смотрит — кириллица и не-kebab-case **жёстко**, форма имени
`ADR-ГГГГ-ММ-ДД-slug.md` жёстко, транслит **эвристикой**, то есть
замечанием. Заодно из раскладки канона убраны плейсхолдеры `<тема>.md`,
приглашавшие называть файлы по-русски.
11. **Два агента вместо обещания.** В каноне была таблица «Что проверяет машина,
а что человек», и её правая колонка три версии описывала судью, которого не
существовало. Судьи заведены и разведены по глубине: **`doc-consistency`**
(документ ↔ документ ↔ openspec: факт в двух домах, прямое противоречие,
поведение в `architecture.md` вместо спек, ADR без ссылки и парного статуса,
число без провенанса, заглушка вместо честной строки); **`doc-code-drift`**
(документ ↔ код по закрытому перечню фактов). Оба зовутся раз в спринт на
сессии, а также после adopt и после upgrade, на весь канон разом.
**Что сделать проекту:**
1. Переименовать заголовок секции в `docs/tasks/ROADMAP.md`: `## Разработка`
`## Сопровождение` (или `## Tooling``## Operations`, если индекс
английский). **`check --fix` этого не сделает**: регистр канонической секции
он правит сам, а чужую секцию только называет ошибкой — смысл за человеком.
2. Поправить поле `- **Секция:**` в файлах целей, которые в ней лежат. Порядок
именно такой: сперва заголовок, потом `python3 tasks.py check --dir
docs/tasks` покажет расхождение поимённо.
3. Перечитать состав секции: цели про выкладку, метрики, логи и инфраструктуру,
если они лежали в `Направлениях` за неимением места, переезжают сюда.
4. Прогнать `python3 tasks.py check --dir docs/tasks --fix`. За один проход он
переставит секции роадмапа в канонический порядок (`Готово` уедет вниз вместе
со всем содержимым), поправит отбивку заголовков и **переведёт записи на
типы**: перенесёт значение из тега `kind:` и префикса `[goal]`/`[idea]` в поле
`Тип`, снимет тег, поставит эмодзи в заголовок, переименует `Секция`
`Категория` у задач и снесёт сырьё в конец категорий.
5. Разобрать то, что `--fix` вернул пометкой `НЕОДНОЗНАЧНО`. Главный случай —
**записи без типа**: заведённые до появления рода работы, они не несут ни
тега, ни префикса, и машина их не угадывает (`feature` от `chore` не
отличает). Проставить руками: `edit <слаг> --type …`.
6. Дописать новые обязательные разделы у задач, которые собираются в спринт:
`Воспроизведение` у каждого `fix`, `Вопрос` и `Куда ляжет ответ` у каждого
`research`. Не «заодно по всему беклогу», а порциями переоценки: `check`
ошибкой это не считает, отказывает только `sprint take`. Сколько задач готово
к взятию, печатает блок здоровья `check`.
7. Прогнать `python3 docs.py check`: он назовёт имена файлов не по правилу.
Кириллицу и не-kebab-case править обязательно, транслит — по решению
человека. **Переименование ADR это перенос ссылок**: слаг стоит в
`adr/README.md`, в `architecture.md` и в чужих документах, и делается одним
проходом, иначе останутся битые ссылки (их `docs.py` потом и покажет).
8. `docs/.pm.json`: `"canon": 4`.
9. Позвать **обоих судей**`doc-consistency` и `doc-code-drift`, шагом 6
`upgrade`. Пунктов выше девять, половина из них ручная, и именно здесь видно,
какие сделаны только наполовину: переименования секций и полей разводят
документы, а `check` сверяет число версии, а не существо. Первый прогон на
живом проекте вдобавок самый урожайный — правило единственного дома до сих пор
никто не проверял. Разбирать порциями, а не одним заходом.
## Версия 3 — 2026-08-04
Роадмап стал **состоянием проекта**, а не очередью работ: цель — возможность
приложения, задача — шаг к ней, достигнутое из роадмапа не исчезает. Плюс род
работы, раздел «Затрагивает» и новое умолчание профиля ревью. Раскладка меняется
в одном файле, но переименование и смена секций тянут за собой ссылки, поэтому
шаги делаются одним заходом.
**Что добавилось:**
1. **Род работы** — тег `kind:<род>` в мете задачи, словарь закрыт:
`feature` | `fix` | `chore` | `research`. Обязателен у задачи, у цели
запрещён. `sprint take` без него отказывает, `check` о пропаже напоминает
замечанием. Определение — [canon.md](canon.md), раздел `tasks/`; смысл и
причина, почему тегом, — в SKILL.md скилла `tasks`, раздел «Род работы».
2. **Раздел «Затрагивает»** в теле задачи — перечень границ, которых изменение
касается (эндпоинт, таблица и миграция, формат на диске, публичный тип). Как
и критерии приёмки, требуется к взятию в спринт, а не к заведению.
3. **Секции роадмапа** — четыре вместо двух и **канонические**, в отличие от
секций беклога: `Готово` (достигнутые цели строкой с датой, без ссылки на
файл), `Запланировано` (очередь значима), `Направления` (очереди нет),
`Разработка` (инструмент и процесс, не возможности приложения). Английский
вариант — `Done` | `Planned` | `Directions` | `Tooling`, один язык на весь
индекс. Переименованию проектом не подлежат: у каждой свой смысл, и в первую
пишет сам `close`; `tasks.py check` проверяет состав.
4. **Форма заголовка записи** — по типу: задача отвечает на «что нужно сделать»
и пишется глаголом в неопределённой форме («Не отбрасывать молча лишние
символы»), цель — на «что приложение будет уметь», идея просто называет, о
чём она. `check` считает заголовки не в форме действия и печатает число в
блоке здоровья. Годность формулировки — не машине: её смотрит новый агент
`task-form` (форма записи, только чтение), а язык текста — `doc-wording`.
5. **Заголовки секций — с прописной, после заголовка пустая строка**, во всех
индексах. Написание канонических секций и отбивку правит `check --fix`; он
же сводит написание секции в мете файла с заголовком индекса.
6. **Язык проектных текстов** — [language.md](language.md), общий дом для
документов канона, задач, решений ADR и записок разведки: информационный
стиль (глагол вместо отглагольного существительного, активный залог, факт
вместо оценки, стоп-слова, параллельность), таблицы англицизмов и жаргона и
то, что из стиля отброшено намеренно. Проектных файлов не добавляет и
раскладку не меняет — это правила письма, а не новый слот.
7. **Умолчание профиля ревью сменилось** — это не раскладка, но проектный текст
под него уже написан. `standard` стал рабочим умолчанием: миграция схемы,
публичный контракт и инвариант ступень больше **не** поднимают, `wide`
означает новое понятие или структурную единицу. Подраздел «Триггеры профиля»
в `docs/review.md` остаётся на месте, но его содержимое надо перечитать.
**Что переехало:** `docs/tasks/PLAN.md``docs/tasks/ROADMAP.md`; достигнутая
цель — из небытия в секцию `Готово`: `close <цель> --implemented` удаляет файл, но
**оставляет строку с датой**. Прежде роадмап отвечал только «что осталось», и
половину его вопроса вели прозой руками. Вместе с
файлом переименован ключ конфига `tasks.plan``tasks.roadmap` и токены
команд: `--index plan``--index roadmap`, `init --plan-sections`
`--roadmap-sections`, `init --plan``--roadmap`. Старый ключ в
`docs/.pm.json` не игнорируется молча — `tasks.py` останавливается и называет
переименование.
**Что удалено:** тип `[epic]`. Он был зонтиком между целью и задачами; зонтиком
стала цель, а слишком крупный шаг дробится на шаги помельче под ней. Ноль
употреблений на 97 записей двух живых проектов.
**Что сделать проекту:**
1. `git mv docs/tasks/PLAN.md docs/tasks/ROADMAP.md`.
2. Починить ссылки на прежнее имя: `grep -rn 'PLAN\.md' docs/ CLAUDE.md`
заголовок самого файла («# План» → «# Роадмап»), строка в `docs/tasks/BACKLOG.md`,
упоминания в `docs/passport.md` и в телах задач.
3. `docs/.pm.json`: ключ `tasks.plan`, если он там был, — в `tasks.roadmap`.
4. Проставить род работы живым задачам: `python3 tasks.py check --dir docs/tasks`
перечислит те, у кого его нет. Задним числом весь беклог не переоформляется —
род нужен к взятию, так что порядок такой: сперва то, что берётся в ближайший
спринт, остальное по ходу переоценки.
5. Дописать раздел «Затрагивает» — тем же порядком и по той же причине: сперва
набор спринта, остальное по мере того, как задача попадает в работу.
6. Перечитать «Триггеры профиля» в `docs/review.md`: строки вида «миграция →
`deep`» теперь дублируют умолчание с обратным знаком. Оставить там только то,
что для этого проекта считается **новым понятием** и **правилом
идентичности**, — и убрать остальное, иначе проект возвращает себе прежнюю
частоту полного набора уточнением.
7. Переименовать секции роадмапа: `порядок``Запланировано`, `темы`
`Направления`; завести `Готово` **первой** и `Разработка` последней
(порядок секций поменялся в версии 4 — если едешь сразу на неё, заводи
`Готово` последней и не переставляй дважды).
Прозаические разделы вроде «Что уже пройдено», которые велись руками,
разложить: звенья — строками в `Готово` (дата, слаг, что стало возможно),
обоснование очереди оставить прозой в `Запланировано`. Любой `##` в индексе
проверка считает секцией, и теперь `check` называет чужую секцию ошибкой.
8. Переформулировать цели ответом на **«что приложение будет уметь»**: не
«Работа со слиянием», а «Исход слияния не зависит от порядка доставки».
Свойство поведения — законная цель. Цель, которая не про приложение
(процесс, инструмент), переезжает в `Разработка`.
9. `[epic]`, если он в проекте заводился: это либо цель, либо набор задач под
общей целью. `check` назовёт его неизвестным типом.
10. Прогнать `python3 tasks.py check --dir docs/tasks --fix`: он поднимет
написание канонических секций, поставит отбивку после заголовков и сведёт
секцию в мете файлов с заголовками индексов. Секции беклога проект
переименовывает сам — их имена он выбирал, и трогать их скрипт не вправе.
11. Переписать заголовки задач в форму действия — по мере того, как задача
попадает в работу, а не «заодно»: `check` печатает их число, а `task-form`
предложит формулировки на замену пачкой.
12. Прочитать [language.md](language.md) — и **ничего не переписывать задним
числом**. Правила языка применяются к тому, что пишется и правится сейчас;
сплошная вычитка старых документов стоит дороже, чем даёт.
13. `docs/.pm.json`: `"canon": 3`.
## Версия 2 — 2026-08-03
Шапка записи ADR — мета-блоком общей формы, и у статуса появился объявленный
дом. Раскладка не менялась: правка касается одного шаблона.
**Что добавилось:** поле `- **Статус:**` в шапке `docs/adr/template.md`
`заменено на ADR-…` либо `устарело`, у активной записи поля нет. Правило
«старая запись получает статус» было и раньше ([canon.md](canon.md), `adr/`),
но места под него шаблон не отводил: каждая запись изобретала своё, а колонка
«Статус» таблицы `adr/README.md` брала его оттуда, где он у каждого свой.
**Что переехало:** поля `Дата` и `Источник` в шаблоне стали жирными
(`- **Дата:**`, `- **Источник:**`) — та же форма, что у меты задачи и у записи
журнала дефектов: поле на строку, имя жирным.
**Что удалено:** ничего.
**Что сделать проекту:**
1. Привести `docs/adr/template.md` к скелету версии 2
([skeletons.md](skeletons.md), раздел `docs/adr/template.md`).
2. В существующих записях `docs/adr/ADR-*.md`: жирным поля шапки; если статус
записан прозой или заголовком — перенести его полем `- **Статус:**` в шапку
и сверить с колонкой «Статус» таблицы в `docs/adr/README.md`.
3. `docs/.pm.json`: `"canon": 2`.
## Версия 1 — 2026-08-03
Первая версия. Проект любой прежней раскладки приводится к ней скиллом `canon`
в режиме `adopt`, а не `upgrade`.
**Что вводится:** раскладка целиком — см. [canon.md](canon.md).
**Что сделать проекту, который приходит из свободной раскладки:**
1. `docs/.pm.json` с `{"canon": 1}` и путём миграций, если БД есть.
2. Скелет канона целиком; незаполненное — одной честной строкой.
3. `docs/specs/` разобрать: поведение — в `openspec/specs/`, обзор — в
`docs/architecture.md`, знание о чужих системах — в `docs/research/`.
Дубли capability удалить, сверив поимённо.
4. `docs/plan.md``docs/tasks/PLAN.md`, шаги плана — целями в «порядок».
5. `BRIEF.md``docs/passport.md`.
6. `docs/backlog/``docs/tasks/`.
7. `docs/review-journal.md` или `docs/review/journal.md``docs/review.md`,
плюс раздел настройки конвейера.
8. `docs/drafts/` растворить: идея → задача `[idea]`, намеренный отказ → ADR,
порядок работ → `PLAN.md`.
9. `docs/review-brief.md`, если заводился, удалить: его разделы разошлись по
документам канона.
10. `conventions.md``conventions/`, `local-research.md``research/`.
11. Завести `docs/security.md` с периметром первой строкой и `docs/adr/`.
12. В `CLAUDE.md`: severity рядом с каждым инвариантом; семантика гейта (чем
краснеет безусловно, где логи, чего в нём нет и кто тогда гоняет дорогое);
**имя основной ветки**; запреты с путями; где `testdata` и куда писать
временное; **что считается необратимым**; общий станок; ориентир по размеру
спринта. Убрать раздел «Процесс», если он пересказывает пайплайн.
13. В `openspec/config.yaml` оставить только нужды генерации и ссылки.
14. Добавить шаг `docs.py check` в гейт проекта.
**Копии правил в шаблонах, которые версия 1 уносит в проект** — их правка в
каноне обязана появляться здесь отдельной версией:
| Что копируется | Дом определения |
| --- | --- |
| форма записи журнала дефектов в `docs/review.md` | `av-dev-pipeline/skills/review-pipeline/references/review-journal.md` |
| правило заведения ADR в `docs/adr/README.md` | [canon.md](canon.md), раздел `adr/` |