Языковые правила лежали внутри скилла tasks: англицизмы, неизвестные термины, «сложность формулировки — не признак сложности работы». Три пункта из практики, без общей опоры и без ответа на «а что ещё сюда относится». Дом у языка теперь один — canon/references/language.md. Не в tasks, хотя пришли правила оттуда: они относятся к документам канона, решениям ADR, запискам разведки и сообщениям коммитов в той же мере, что к задачам, а каталог задач и сам часть docs/. Раскладка отвечает, где текст лежит, — этот файл отвечает, каким он должен быть словами. Основа — информационный стиль Ильяхова, взятый не целиком. Взято: полезное действие, глагол вместо отглагольного существительного, активный залог, факт вместо оценки, стоп-слова, одна мысль — одно предложение, параллельность, работающий заголовок. Отброшенное названо вслух, и это отдельный раздел. Инфостиль написан для текстов, где читателя надо удержать, а проектный текст читают потому, что надо. Парцелляция ломает причинную связь, а в решении ценность именно в ней. Запрет вводных целиком режет «если» и «в отличие от» — условия, то есть сведения. Скобки в технической записи несут уточнение: имя команды, единицы, слаг. Без этого раздела правило читается как «пиши короче», и первый же агент начинает резать «поэтому» и «иначе». «Снять корону с себя и надеть на клиента» переведено на здешнего читателя: клиент — ты сам через квартал и тот, кто возьмёт задачу. Таблицы англицизмов и жаргона взяты из скилла prepare-jira-text и дополнены; в устав агента они уехали помеченной копией. Устав обязан быть самодостаточным — он не разрешает пути плагина и не ходит по ссылкам, — а два дома у одного правила здесь уже трижды расходились. scripts/copies.py считает теперь 4 копии при 4 домах. У агента вычитки правил стало двенадцать, разделены на форму записи (только для задач) и язык (для любого проектного текста). Находки докладываются в этом порядке: форма меняет решение «брать или не брать», язык — только цену чтения. DECISIONS тема 21 (ЛЛЛ–ООО, следствия 86–88), changelog канона v3 — пункт 6 и шаг переезда «прочитать и ничего не переписывать задним числом». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
184 lines
16 KiB
Markdown
184 lines
16 KiB
Markdown
# Журнал версий канона
|
||
|
||
Одна запись на версию. Проект знает свою версию из `docs/.pm.json`; `canon
|
||
upgrade` идёт по записям снизу вверх от версии проекта до текущей и делает то,
|
||
что в них названо.
|
||
|
||
Правило записи: **что добавилось, что переехало, что удалено, что сделать
|
||
проекту**. Без последнего пункта запись бесполезна — по ней и работает
|
||
`upgrade`.
|
||
|
||
Версия — целое число. Обратной совместимости у канона нет: есть «приведён» и «не
|
||
приведён».
|
||
|
||
---
|
||
|
||
## Версия 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-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. Переименовать секции роадмапа: `порядок` → `Запланировано`, `темы` →
|
||
`Направления`; завести `Готово` **первой** и `Разработка` последней.
|
||
Прозаические разделы вроде «Что уже пройдено», которые велись руками,
|
||
разложить: звенья — строками в `Готово` (дата, слаг, что стало возможно),
|
||
обоснование очереди оставить прозой в `Запланировано`. Любой `##` в индексе
|
||
проверка считает секцией, и теперь `check` называет чужую секцию ошибкой.
|
||
8. Переформулировать цели ответом на **«что приложение будет уметь»**: не
|
||
«Работа со слиянием», а «Исход слияния не зависит от порядка доставки».
|
||
Свойство поведения — законная цель. Цель, которая не про приложение
|
||
(процесс, инструмент), переезжает в `Разработка`.
|
||
9. `[epic]`, если он в проекте заводился: это либо цель, либо набор задач под
|
||
общей целью. `check` назовёт его неизвестным типом.
|
||
10. Прогнать `python3 tasks.py check --dir docs/tasks --fix`: он поднимет
|
||
написание канонических секций, поставит отбивку после заголовков и сведёт
|
||
секцию в мете файлов с заголовками индексов. Секции беклога проект
|
||
переименовывает сам — их имена он выбирал, и трогать их скрипт не вправе.
|
||
11. Переписать заголовки задач в форму действия — по мере того, как задача
|
||
попадает в работу, а не «заодно»: `check` печатает их число, а `task-wording`
|
||
предложит формулировки на замену пачкой.
|
||
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/` |
|