скелеты канона догнали канон 12: спринт, версия, чужая проверка
Аудит четырьмя сабагентами показал систематическую дыру: механика правилась, а описывающее её вовне — нет. Дороже всего скелеты: они уезжают в проект. - слоты спринта в скелете CLAUDE.md стали слотами груминга, имена взяты у groom, а не выдуманы заново — журнал версии 12 их уже назвал - "canon": 11 в двух образцах стал плейсхолдером: литерал протухал третий раз подряд, а незамещённый плейсхолдер ломает разбор громко - обещание, что docs.py проверяет форму openspec/config.yaml, снято из трёх мест; владелец назван полным именем, с оговоркой об отсутствии плагина - adopt ставил в гейт проекта один шаг из трёх; соседские ставятся по следу присутствия, следа нет — строка доклада - битая ссылка на tasks/ROADMAP.md из скелета паспорта Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -181,7 +181,8 @@ color: green
|
|||||||
|
|
||||||
**Машинной проверке — вообще ничего.** Всё, что ловит `docs.py check` (пути
|
**Машинной проверке — вообще ничего.** Всё, что ловит `docs.py check` (пути
|
||||||
канона, файлы вне канона, имена файлов, битые ссылки, версия канона, нетронутые
|
канона, файлы вне канона, имена файлов, битые ссылки, версия канона, нетронутые
|
||||||
плейсхолдеры, маркеры долга, форма `openspec/config.yaml`), **не пиши даже
|
плейсхолдеры, маркеры долга) и что ловит `openspec.py check` скилла
|
||||||
|
`av-dev-code:openspec` (форма `openspec/config.yaml`), **не пиши даже
|
||||||
строкой**: это не потерянная находка, а уже проверенное. Повторять машинную
|
строкой**: это не потерянная находка, а уже проверенное. Повторять машинную
|
||||||
проверку словами — заводить второй дом для одного правила.
|
проверку словами — заводить второй дом для одного правила.
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,18 @@ capability), `openspec/config.yaml`.
|
|||||||
меняла `Taskfile`; шаг обязан **краснеть внятно**, если скрипт не найден, а не
|
меняла `Taskfile`; шаг обязан **краснеть внятно**, если скрипт не найден, а не
|
||||||
пропускаться. Передай ему базу диффа (`--base`) той же переменной, что и
|
пропускаться. Передай ему базу диффа (`--base`) той же переменной, что и
|
||||||
остальным шагам гейта: без неё сверка миграций со схемой не гоняется вовсе.
|
остальным шагам гейта: без неё сверка миграций со схемой не гоняется вовсе.
|
||||||
Пример строки покажи человеку — гейт принадлежит проекту, и правит его он;
|
Пример строки покажи человеку — гейт принадлежит проекту, и правит его он.
|
||||||
|
|
||||||
|
**Шагов в гейте три, и они независимы.** `docs.py check` не тянет за собой
|
||||||
|
ни задачи, ни конвейер: без своих строк дрейф каталога задач и формы
|
||||||
|
`openspec/config.yaml` перестаёт ловиться совсем. Ставь соседские шаги по
|
||||||
|
следу присутствия — `<каталог задач>/.tasks.json` есть, значит ставится
|
||||||
|
`tasks.py check --dir <каталог задач>`; `openspec/config.yaml` есть, значит
|
||||||
|
ставится `openspec.py check`. Следа нет — плагина в проекте нет, шаг не
|
||||||
|
ставится, и это **строка доклада**, а не поломка: назови, чего теперь не
|
||||||
|
проверяет никто. У каждого шага своя переменная пути с тем же умолчанием на
|
||||||
|
канонический путь маркетплейса; `$CLAUDE_PLUGIN_ROOT` в гейт не подставляй —
|
||||||
|
он ведёт только в свой плагин;
|
||||||
9. `docs.py check` — до **отсутствия дрейфа раскладки**. Замечания
|
9. `docs.py check` — до **отсутствия дрейфа раскладки**. Замечания
|
||||||
(незаполненные плейсхолдеры, слабое упоминание capability) остаются:
|
(незаполненные плейсхолдеры, слабое упоминание capability) остаются:
|
||||||
незаполненный канон это объявленное переходное состояние из шага 5, а не
|
незаполненный канон это объявленное переходное состояние из шага 5, а не
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
| 🔬 `research` | исход — знание, а не изменение |
|
| 🔬 `research` | исход — знание, а не изменение |
|
||||||
|
|
||||||
**Схемы записи здесь нет намеренно.** Какие разделы тип требует, нужна ли ему
|
**Схемы записи здесь нет намеренно.** Какие разделы тип требует, нужна ли ему
|
||||||
цель и берётся ли он в спринт — скилл `av-dev-tasks:tasks`, раздел «Тип
|
цель и берётся ли он в работу — скилл `av-dev-tasks:tasks`, раздел «Тип
|
||||||
записи», подробно — по файлу на тип в его `references/task-<тип>.md`. Ссылки в
|
записи», подробно — по файлу на тип в его `references/task-<тип>.md`. Ссылки в
|
||||||
дерево того плагина здесь нет намеренно: он ставится отдельно, и путь наружу
|
дерево того плагина здесь нет намеренно: он ставится отдельно, и путь наружу
|
||||||
разрешился бы не всегда. Канон фиксирует **словарь**, потому что
|
разрешился бы не всегда. Канон фиксирует **словарь**, потому что
|
||||||
@@ -400,7 +400,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
|
|
||||||
Отдельного типа для незаполненной записи нет: «ещё не описано» — состояние, а не
|
Отдельного типа для незаполненной записи нет: «ещё не описано» — состояние, а не
|
||||||
род работы, и называется оно **`research` без раздела «Вопрос»**. Такая запись в
|
род работы, и называется оно **`research` без раздела «Вопрос»**. Такая запись в
|
||||||
спринт не берётся и лежит в конце своей категории.
|
работу не берётся и лежит в конце своей категории.
|
||||||
|
|
||||||
Раскладку, форму записи и алгоритм работы над каждым типом держит скилл `tasks`.
|
Раскладку, форму записи и алгоритм работы над каждым типом держит скилл `tasks`.
|
||||||
|
|
||||||
@@ -422,8 +422,10 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
- **где `testdata`** и что в них лежит; **куда писать временное**;
|
- **где `testdata`** и что в них лежит; **куда писать временное**;
|
||||||
- **что считается необратимым** — единственный дом: от обратимости зависит вся
|
- **что считается необратимым** — единственный дом: от обратимости зависит вся
|
||||||
шкала ранжирования триажа и право проходов на `critical`;
|
шкала ранжирования триажа и право проходов на `critical`;
|
||||||
- **общий станок**, врывающийся в замороженный спринт; **ориентир по размеру
|
- **что считается сломанным** — красная проверка, обгоняющая развитие;
|
||||||
спринта**.
|
**ориентир по размеру порции**, если он замерялся. Оба слота читает скилл
|
||||||
|
`av-dev-tasks:groom`, и имена их — его; названы они здесь потому, что дом
|
||||||
|
содержимого `CLAUDE.md` один и он тут.
|
||||||
|
|
||||||
### `openspec/config.yaml`
|
### `openspec/config.yaml`
|
||||||
|
|
||||||
@@ -512,10 +514,17 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
| маркеры долга — числом | **протухший факт, разошедшийся с кодом** | `doc-code-drift` |
|
| маркеры долга — числом | **протухший факт, разошедшийся с кодом** | `doc-code-drift` |
|
||||||
| миграция изменена, а `database.md` нет | зависимость в манифесте, не названная в обзоре | `doc-code-drift` |
|
| миграция изменена, а `database.md` нет | зависимость в манифесте, не названная в обзоре | `doc-code-drift` |
|
||||||
| capability без упоминания в `architecture.md` | второй способ там, где обзор обещал единственный | `doc-code-drift` |
|
| capability без упоминания в `architecture.md` | второй способ там, где обзор обещал единственный | `doc-code-drift` |
|
||||||
| `openspec/config.yaml`: имя, `schema`, незаменённый пример, адреса паспорта и `CLAUDE.md`, ключи `rules` против артефактов схемы | **пересказ документа канона в `context` вместо ссылки** | `doc-consistency` |
|
| | **пересказ документа канона в `context` вместо ссылки** | `doc-consistency` |
|
||||||
| версия OpenSpec разошлась с той, на которой сверена форма `config.yaml` | придирки валидатора: сменились ли они | никакой — проявляются отказом `openspec validate --strict` |
|
| | придирки валидатора: сменились ли они | никакой — проявляются отказом `openspec validate --strict` |
|
||||||
| | связность и читаемость | `doc-wording` |
|
| | связность и читаемость | `doc-wording` |
|
||||||
|
|
||||||
|
**Форма `openspec/config.yaml` в левой колонке отсутствует не по забывчивости.**
|
||||||
|
С канона 10 `docs.py` о файле не говорит ничего: имя, `schema`, незаменённый
|
||||||
|
пример, адреса паспорта и `CLAUDE.md`, ключи `rules` и сторож версии OpenSpec —
|
||||||
|
всё это смотрит `openspec.py check` скилла `av-dev-code:openspec`. Плагина
|
||||||
|
конвейера в проекте может не быть; тогда форму не проверяет никто, и это строка
|
||||||
|
доклада.
|
||||||
|
|
||||||
**Агентов двое, и разведены они по глубине, а не по охвату.** `doc-consistency`
|
**Агентов двое, и разведены они по глубине, а не по охвату.** `doc-consistency`
|
||||||
читает только `docs/` и `openspec/`, `doc-code-drift` — весь репозиторий и гоняет
|
читает только `docs/` и `openspec/`, `doc-code-drift` — весь репозиторий и гоняет
|
||||||
читающие команды. Слитый агент делал бы одну половину поверхностной; тот же
|
читающие команды. Слитый агент делал бы одну половину поверхностной; тот же
|
||||||
@@ -540,15 +549,17 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"canon": 11,
|
"canon": <текущая версия>,
|
||||||
"migrations": "internal/store/migrations"
|
"migrations": "internal/store/migrations"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`canon` — версия канона, под которую проект приведён, целым числом: обратной
|
`canon` — версия канона, под которую проект приведён, целым числом: обратной
|
||||||
совместимости у канона нет, есть «приведён» и «не приведён». `migrations` — путь
|
совместимости у канона нет, есть «приведён» и «не приведён». Число подставляет
|
||||||
каталога миграций, если БД есть; по нему `docs.py` делает сверку с
|
`init`, `adopt` или `upgrade`, и берётся оно из `docs.py version`, а не из
|
||||||
`database.md`.
|
образца: литерал в образце протухает на первом же повышении канона.
|
||||||
|
`migrations` — путь каталога миграций, если БД есть; по нему `docs.py` делает
|
||||||
|
сверку с `database.md`.
|
||||||
|
|
||||||
**Ключа `tasks` здесь больше нет.** Настройки каталога задач вернулись в свой
|
**Ключа `tasks` здесь больше нет.** Настройки каталога задач вернулись в свой
|
||||||
файл `<каталог задач>/.tasks.json`, потому что ведёт их другой плагин: конфиг,
|
файл `<каталог задач>/.tasks.json`, потому что ведёт их другой плагин: конфиг,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
# Паспорт проекта
|
# Паспорт проекта
|
||||||
|
|
||||||
Зачем это и для кого. [architecture.md](architecture.md) отвечает «как
|
Зачем это и для кого. [architecture.md](architecture.md) отвечает «как
|
||||||
устроено», [tasks/ROADMAP.md](tasks/ROADMAP.md) — «в каком порядке», паспорт —
|
устроено», [tasks/ROADMAP.md](../tasks/ROADMAP.md) — «в каком порядке», паспорт —
|
||||||
«зачем и для кого».
|
«зачем и для кого».
|
||||||
|
|
||||||
## Цель
|
## Цель
|
||||||
@@ -401,8 +401,9 @@ severity стоит здесь, а не выводится каждым прох
|
|||||||
|
|
||||||
- **Основная ветка:** <имя>
|
- **Основная ветка:** <имя>
|
||||||
- **Необратимое** (спрашивается у человека всегда):
|
- **Необратимое** (спрашивается у человека всегда):
|
||||||
- **Общий станок** — какая проверка, покраснев, врывается в замороженный спринт:
|
- **Что считается сломанным** — какая красная проверка обгоняет развитие,
|
||||||
- **Ориентир по размеру спринта:** 5–8 задач, ориентир а не закон
|
то есть останавливает текущую работу:
|
||||||
|
- **Ориентир по размеру порции:** своё число, если замерялось
|
||||||
- **Что такое «сделана»:** пайплайн проекта пройден + критерии приёмки проверены
|
- **Что такое «сделана»:** пайплайн проекта пройден + критерии приёмки проверены
|
||||||
поимённо
|
поимённо
|
||||||
|
|
||||||
@@ -424,17 +425,26 @@ severity стоит здесь, а не выводится каждым прох
|
|||||||
документов. Проект без конвейера каталога `openspec/` не имеет вовсе, и образец
|
документов. Проект без конвейера каталога `openspec/` не имеет вовсе, и образец
|
||||||
файла, которого у него нет, в скелетах канона лежал бы мёртвым грузом.
|
файла, которого у него нет, в скелетах канона лежал бы мёртвым грузом.
|
||||||
|
|
||||||
Канон о нём всё ещё **высказывается**, но только в одну сторону: `docs.py check`
|
**Форму не проверяет и `docs.py`** — с канона 10 он о файле молчит вовсе.
|
||||||
проверяет форму, **если каталог есть**, и молчит, если его нет. Что именно
|
Проверяет её тот же владелец: скилл `av-dev-code:openspec`, команда
|
||||||
проверяется — [canon.md](canon.md), раздел `openspec/config.yaml`.
|
`openspec.py check`. Плагина конвейера в проекте может не быть — тогда форму не
|
||||||
|
смотрит никто, и это строка доклада, а не поломка. Что канон о файле всё же
|
||||||
|
говорит (единственный дом, а не форма) — [canon.md](canon.md), раздел
|
||||||
|
`openspec/config.yaml`.
|
||||||
|
|
||||||
## `docs/.pm.json`
|
## `docs/.pm.json`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"canon": 11
|
"canon": <текущая версия>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`<текущая версия>` подставляет `init` или `adopt`, целым числом; берётся она из
|
||||||
|
`docs.py version` (строка «канон скрипта»), а не из памяти. Литерал здесь
|
||||||
|
протухает при каждом повышении канона, поэтому его тут и нет: незамещённый
|
||||||
|
плейсхолдер ломает разбор JSON громко, а отставшее число дало бы дрейф молча.
|
||||||
|
|
||||||
Плюс `"migrations": "<путь>"`, если есть БД. Ключа `"tasks"` здесь **нет**:
|
Плюс `"migrations": "<путь>"`, если есть БД. Ключа `"tasks"` здесь **нет**:
|
||||||
настройки каталога задач переехали в свой файл `<каталог задач>/.tasks.json`,
|
настройки каталога задач переехали в свой файл `<каталог задач>/.tasks.json`,
|
||||||
потому что ведёт их другой плагин. Состав ключей — [canon.md](canon.md).
|
потому что ведёт их другой плагин. Состав ключей — [canon.md](canon.md).
|
||||||
|
|||||||
Reference in New Issue
Block a user