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

Имя `.pm.json` пережило плагин `av-dev-pm` на два месяца и указывало в пустоту.
Правило, которое из этого вынуто: имя служебного файла — имя плагина, который
его завёл, и по нему же владельца узнают.

- `docs/.pm.json` → `docs/.docs.json`, запись 13 журнала. Прежнее имя docs.py
  не читает намеренно: по этому числу upgrade решает, какие записи применять,
  и два дома разъехались бы молча ровно там, где это дороже всего. Вместо
  совместимости — узнавание: check видит старый файл и печатает готовую git mv
- у каталога задач появилась своя версия формата — ключ `tasks` в
  `.tasks.json`, свой журнал версий и своё повышение. До сих пор её не было
  вовсе, хотя docs.py в комментарии уверенно на неё ссылался: описание
  опережало механику ровно так, как сказано в решении 195
- число своё, а не копия канонического: плагин ставится в одиночку, и у
  проекта без docs/ версии канона нет — сверять было бы не с чем
- конфиг задач стал обязательным (init и adopt apply пишут его всегда), check
  сверяет число, `check --fix` его не приписывает: приписанное объявляло бы
  каталог приведённым к формату, шагов которого никто не делал
- переезды 11 и 12 в новый журнал задним числом не переписаны — версия 1
  велит догнать формат по журналу канона, называя признаки отставания
  поимённо (каталог в docs/tasks/, живой SPRINT.md)
- запись 60 в DECISIONS со следствиями 200–203; отдельно разведено с решением
  F, где `.docs.json` отвергался как указатель путей: отвергнут был указатель,
  а не имя
This commit is contained in:
av
2026-08-11 10:35:39 +03:00
parent 12b77c3393
commit 863769406f
22 changed files with 474 additions and 93 deletions
+21 -8
View File
@@ -65,7 +65,7 @@ CLAUDE.md памятка агенту: что это, ст
severity, команды, семантика гейта, запреты
AGENTS.md необязателен, лежит рядом; читается теми же
docs/
.pm.json версия канона и пути, нужные проверкам
.docs.json версия канона и пути, нужные проверкам
passport.md | passport/ зачем и для кого; чем НЕ является; сценарии
architecture.md | architecture/ как сложено — обзор; окружение и эксплуатация
database.md | database/ схема хранилища; представление данных и настройки
@@ -119,7 +119,7 @@ openspec/
| `review.*` | процессный | — (настройка самого конвейера, слой **над** темами) |
| `adr.*` | процессный | — |
| `research.*` | процессный | — |
| `.pm.json` | процессный | — (служебный файл, не документ) |
| `.docs.json` | процессный | — (служебный файл, не документ) |
**Список тем открытый, и это не послабление, а механизм.** Категории
`источник` и `процессный` **закрыты** — они перечислены здесь поимённо и
@@ -354,8 +354,10 @@ kebab-case.** Причина не эстетическая: имя файла с
### `tasks/`
**Каталог задач канону не принадлежит.** Его ведёт отдельный плагин
`av-dev-tasks` — своим скриптом, своим конфигом `<каталог>/.tasks.json` и своей
версией формата. Канон **резервирует место** в `docs/` и внутрь не смотрит:
`av-dev-tasks` — своим скриптом, своим конфигом `<каталог>/.tasks.json`, своей
версией формата в нём же и своим журналом версий. Канон о том числе не
высказывается и его не двигает: повышает каталог задач тот, кто его ведёт.
Канон **резервирует место** в `docs/` и внутрь не смотрит:
`docs.py` каталог не открывает, его отсутствия не считает дрейфом и согласованность
задач не проверяет. Проект, поставивший только канон документов, задач не ведёт
вовсе, и отказом это быть не может.
@@ -546,7 +548,7 @@ kebab-case.** Причина не эстетическая: имя файла с
архитектуру с кодом» задача без дна, и агент, которому её поставили, выдаёт
правдоподобную труху вместо находок.
## `docs/.pm.json`
## `docs/.docs.json`
```json
{
@@ -562,12 +564,23 @@ kebab-case.** Причина не эстетическая: имя файла с
`migrations` — путь каталога миграций, если БД есть; по нему `docs.py` делает
сверку с `database.md`.
**Имя файла — имя плагина, который его завёл.** Канон документов ведёт
`av-dev-docs`, поэтому `.docs.json`; у каталога задач по тому же правилу
`.tasks.json`, у конвейера — `openspec/config.yaml`. До версии 13 файл звался
`.pm.json` — по плагину `av-dev-pm`, который распался на четыре и которого
больше нет; имя пережило владельца и указывало в пустоту. Прежнее имя `docs.py`
не читает: два дома для одной версии канона расходятся молча, а переименование
стоит одну команду (версия 13 журнала, и `check` называет её сам, когда видит
старый файл).
**Ключа `tasks` здесь больше нет.** Настройки каталога задач вернулись в свой
файл `<каталог задач>/.tasks.json`, потому что ведёт их другой плагин: конфиг,
лежащий в `docs/`, был бы домом, которого нет у проекта, поставившего учёт работ
без канона документов. Состав ключей описывает тот плагин, а не канон. Прежний
ключ читается, пока живы непереехавшие проекты, и `tasks.py` говорит о нём
замечанием на каждом прогоне — версия 8 журнала просит его убрать.
без канона документов. Состав ключей описывает тот плагин, а не канон. Там же —
**версия формата задач**, и она своя: у проекта без `docs/` версии канона нет
вовсе, сверять её было бы не с чем. Прежний ключ читается, пока живы
непереехавшие проекты, и `tasks.py` говорит о нём замечанием на каждом
прогоне — версия 8 журнала просит его убрать.
Ключей будет больше по мере роста проверок; неизвестный ключ `docs.py`
игнорирует, отсутствующий — считает «проверка неприменима» и говорит об этом
@@ -1,8 +1,15 @@
# Журнал версий канона
Одна запись на версию. Проект знает свою версию из `docs/.pm.json`; `canon
Одна запись на версию. Проект знает свою версию из `docs/.docs.json`; `canon
upgrade` идёт по записям снизу вверх от версии проекта до текущей и делает то,
что в них названо.
что в них названо. Записи ниже версии 13 зовут этот файл прежним именем,
`docs/.pm.json`, — так и было на день записи, и переписывать историю мы не
станем; переименование делает запись 13.
**Каталог задач этим журналом не повышается.** У него своя версия формата и свой
журнал — `references/changelog.md` скилла `av-dev-tasks:tasks`. Записи 8, 11 и 12
трогали его в те времена, когда своего числа у него не было; впредь запись канона
вправе позвать соседа, но не двигать его версию.
Правило записи: **что добавилось, что переехало, что удалено, что сделать
проекту**. Без последнего пункта запись бесполезна — по ней и работает
@@ -13,6 +20,51 @@ upgrade` идёт по записям снизу вверх от версии п
---
## Версия 13 — 2026-08-11
Служебный файл канона переименован: `docs/.pm.json``docs/.docs.json`. Имя
досталось от плагина `av-dev-pm`, который распался на четыре и которого больше
нет: файл пережил владельца и указывал в пустоту. Правило простое и теперь
соблюдается всеми тремя: **имя служебного файла — имя плагина, который его
завёл**, `.docs.json` — канон, `.tasks.json` — задачи, `openspec/config.yaml`
конвейер.
**Что изменилось.** `docs.py` читает только новое имя. Прежнее он не читает
намеренно: два дома для одной версии канона расходятся молча, а тут расхождение
стоило бы дорого — по этому числу `upgrade` решает, какие записи применять.
Файл под старым именем `check` узнаёт и называет отдельной строкой с готовой
командой, а не жалуется на пропажу.
**Что появилось у соседа.** У каталога задач теперь есть **своя версия
формата** — ключ `tasks` в `<каталог задач>/.tasks.json`, — и свой журнал версий
в скилле `av-dev-tasks:tasks`. До сих пор её не было вовсе: формат задач менялся
записями этого журнала (8, 11, 12), хотя каталог принадлежит другому плагину и
ставится без канона документов. Канон это число не двигает.
**Что сделать проекту.**
1. `git mv docs/.pm.json docs/.docs.json` — одним коммитом с шагом 2. Содержимое
не меняется: ключи те же.
2. **Поправить упоминания прежнего имени** в своих файлах — `CLAUDE.md`, гейт,
`README.md`, `docs/**`. Битой ссылкой это чаще всего не выглядит (файл
служебный, на него ссылаются прозой), поэтому `docs.py check` таких упоминаний
не ловит: ищи `grep -rn '\.pm\.json'` по репозиторию.
3. **Объявить версию формата задач**, если каталог задач в проекте есть:
`<каталог задач>/.tasks.json` с ключом `"tasks": <версия>`. Файла нет вовсе —
заведи, он теперь обязателен: версия не настройка, от которой можно
отказаться. Какое число ставить и что сделать перед этим, говорит журнал
владельца — **позови скилл `av-dev-tasks:tasks`**, здесь этих шагов нет
намеренно: второй перечень чужих шагов разошёлся бы с первым.
4. Гейт не меняется: шаги те же, версию задач сторожит `tasks.py check`, который
в нём уже стоит.
5. `docs/.docs.json`: `"canon": 13`.
**Чего делать не надо.** Ключи в файле не трогаются, документы не переезжают,
записи задач не меняются: версия 13 — про имена служебных файлов и про то, кто
чью версию двигает.
---
## Версия 12 — 2026-08-09
Спринты отменены. Работа идёт задача за задачей, и замороженный набор перестал
@@ -117,7 +117,7 @@
со строкой «запись лежит сжатой и распаковывается целиком».
```
Нет БД — файла нет, и в `docs/.pm.json` нет ключа `migrations`.
Нет БД — файла нет, и в `docs/.docs.json` нет ключа `migrations`.
## `docs/security.md`
@@ -438,7 +438,7 @@ severity стоит здесь, а не выводится каждым прох
говорит (единственный дом, а не форма) — [canon.md](canon.md), раздел
`openspec/config.yaml`.
## `docs/.pm.json`
## `docs/.docs.json`
```json
{
@@ -452,5 +452,10 @@ severity стоит здесь, а не выводится каждым прох
плейсхолдер ломает разбор JSON громко, а отставшее число дало бы дрейф молча.
Плюс `"migrations": "<путь>"`, если есть БД. Ключа `"tasks"` здесь **нет**:
настройки каталога задач переехали в свой файл `<каталог задач>/.tasks.json`,
потому что ведёт их другой плагин. Состав ключей — [canon.md](canon.md).
настройки каталога задач и версия их формата переехали в свой файл `<каталог
задач>/.tasks.json`, потому что ведёт их другой плагин. Состав ключей —
[canon.md](canon.md).
Имя файла — по плагину-владельцу, `av-dev-docs`. До версии 13 он звался
`.pm.json`, по распавшемуся `av-dev-pm`; проект с прежним именем `docs.py check`
называет отдельной строкой и зовёт переименовать.