канон отпустил каталог задач: docs.py не зовёт tasks.py, конфиг разъехался
Пока владелец был один, docs/tasks/ числился слотом канона: docs.py требовал каталог, звал внутрь чужой скрипт подпроцессом и выдавал его дрейф за свой, а настройки задач жили ключом tasks в docs/.pm.json. Для проекта, поставившего только документы, всё это отказ на ровном месте — задач он не ведёт, и требовать их не за что. Раскол вскрыл это немедленно и молча: check_tasks искал tasks.py по пути parents[2]/tasks/scripts, то есть внутри своего плагина, и после переезда скатывался в ветку «скрипт не найден» на каждом прогоне. Проверка выглядела живой и не проверяла ничего. Теперь docs.py про задачи не говорит ни слова: check_tasks снят целиком, каталог остаётся в NOT_DOCS, его отсутствие дрейфом не считается. Канон резервирует место в docs/ и внутрь не смотрит. Дом настроек каталога задач вернулся в свой файл — <каталог>/.tasks.json. Прежний ключ tasks в docs/.pm.json читается, только когда своего файла нет, и скрипт говорит, куда его перенести; есть оба — побеждает свой, и об этом тоже говорится вслух. Порядок именно такой, потому что docs/ принадлежит другому плагину: дом настроек в чужом дереве это дом, которого у половины проектов нет. Заодно закрыта дыра, которую сам же и открыл первый вариант правки: битый docs/.pm.json ронял бы задачи даже при живом своём конфиге. Чужой файл здесь только повод для замечания, и его поломка не наша. Проверено на четырёх случаях — только чужой конфиг, оба, свой плюс битый чужой (код 0), только битый чужой (код 3, окружение). Канон повышен до версии 8 с записью, выполнимой upgrade. В ней названо и то, что легко потерять: раньше согласованность задач тянул за собой docs.py check, и проект, у которого в гейте стоял только он, обязан добавить второй шаг — иначе дрейф индексов перестанет ловиться молча. Гейт зелёный. Оба скрипта прогнаны: docs.py check на фикстуре про задачи не упоминает, tasks.py check код 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,8 +75,8 @@ docs/
|
||||
adr.md | adr/ почему решено так; статусы, правило замены
|
||||
review.md | review/ настройка конвейера под проект + журнал дефектов
|
||||
<своя тема>.md | <своя тема>/ всё, что проект счёл нужным проверять
|
||||
tasks/ скилл tasks: items/, ROADMAP.md, BACKLOG.md,
|
||||
SPRINT.md, REJECTED.md
|
||||
tasks/ каталог задач — плагин av-dev-tasks, не канон:
|
||||
место зарезервировано, наличия канон не требует
|
||||
openspec/
|
||||
config.yaml только нужды генерации артефактов + ссылки
|
||||
specs/<capability>/spec.md что система делает — нормативно
|
||||
@@ -115,7 +115,7 @@ openspec/
|
||||
| `CLAUDE.md`, `AGENTS.md` | источник | `autotests` (семантика гейта); инварианты — сквозные |
|
||||
| `openspec/specs/` | источник | `requirements` |
|
||||
| `openspec/config.yaml` | процессный | — (настройка порождения артефактов, слой **до** тем) |
|
||||
| `tasks/` | процессный | — |
|
||||
| `tasks/` | процессный | — (чужое владение: плагин `av-dev-tasks`) |
|
||||
| `review.*` | процессный | — (настройка самого конвейера, слой **над** темами) |
|
||||
| `adr.*` | процессный | — |
|
||||
| `research.*` | процессный | — |
|
||||
@@ -353,9 +353,16 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
|
||||
### `tasks/`
|
||||
|
||||
Раскладку, форму записи и команды держит скилл `tasks` — канон фиксирует имена
|
||||
файлов (`items/`, `ROADMAP.md`, `BACKLOG.md`, `SPRINT.md`, `REJECTED.md`) и то,
|
||||
от чего зависит, читается ли проект как продукт.
|
||||
**Каталог задач канону не принадлежит.** Его ведёт отдельный плагин
|
||||
`av-dev-tasks` — своим скриптом, своим конфигом `<каталог>/.tasks.json` и своей
|
||||
версией формата. Канон **резервирует место** в `docs/` и внутрь не смотрит:
|
||||
`docs.py` каталог не открывает, его отсутствия не считает дрейфом и согласованность
|
||||
задач не проверяет. Проект, поставивший только канон документов, задач не ведёт
|
||||
вовсе, и отказом это быть не может.
|
||||
|
||||
Раскладку, форму записи и команды держит скилл `av-dev-tasks:tasks`. Ниже — то,
|
||||
от чего зависит, читается ли проект как продукт: канон высказывается об этом
|
||||
потому, что роадмап отвечает на вопрос о **системе**, а не о работах.
|
||||
|
||||
**`ROADMAP.md` отвечает на «что приложение уже умеет и чего ещё не умеет».** Это
|
||||
не очередь работ: цель — **возможность приложения**, задача — шаг к ней.
|
||||
@@ -563,30 +570,22 @@ OpenSpec переименует артефакт или сменит схему
|
||||
|
||||
```json
|
||||
{
|
||||
"canon": 7,
|
||||
"migrations": "internal/store/migrations",
|
||||
"tasks": {
|
||||
"backlog": "INDEX.md"
|
||||
}
|
||||
"canon": 8,
|
||||
"migrations": "internal/store/migrations"
|
||||
}
|
||||
```
|
||||
|
||||
`canon` — версия канона, под которую проект приведён, целым числом: обратной
|
||||
совместимости у канона нет, есть «приведён» и «не приведён». `migrations` — путь
|
||||
каталога миграций, если БД есть; по нему `docs.py` делает сверку с
|
||||
`database.md`. `tasks` — настройки каталога задач, переехавшие сюда из прежнего
|
||||
`<tasks>/.tasks.json`: **один конфиг на весь канон, а не по одному на каталог**.
|
||||
Внутри `tasks` — **только имена файлов и заголовков** (`items`, `backlog`,
|
||||
`roadmap`, `sprint`, `rejected`, `sprint_section`, `oracle_word` и заголовки
|
||||
разделов тела: `criteria_heading`, `surface_heading`, `questions_heading`,
|
||||
`completion_heading`, `repro_heading`, `question_heading`, `answer_heading`,
|
||||
`scope_heading`), и ключ пишется, лишь когда имя отличается от умолчания.
|
||||
**Словаря типов здесь нет** — он закрыт каноном, а не настраивается проектом:
|
||||
настраиваемый словарь типов разъехался бы на синонимах ровно так же, как
|
||||
открытый. **Категорий беклога здесь тоже нет:** их дом — заголовки `##` самого
|
||||
индекса, и второй список сразу разошёлся бы с первым. Неизвестный ключ `tasks.py`
|
||||
отвергает кодом 3, поэтому лишнее слово в этом объекте останавливает работу с
|
||||
задачами целиком.
|
||||
`database.md`.
|
||||
|
||||
**Ключа `tasks` здесь больше нет.** Настройки каталога задач вернулись в свой
|
||||
файл `<каталог задач>/.tasks.json`, потому что ведёт их другой плагин: конфиг,
|
||||
лежащий в `docs/`, был бы домом, которого нет у проекта, поставившего учёт работ
|
||||
без канона документов. Состав ключей описывает тот плагин, а не канон. Прежний
|
||||
ключ читается, пока живы непереехавшие проекты, и `tasks.py` говорит о нём
|
||||
замечанием на каждом прогоне — версия 8 журнала просит его убрать.
|
||||
|
||||
Ключей будет больше по мере роста проверок; неизвестный ключ `docs.py`
|
||||
игнорирует, отсутствующий — считает «проверка неприменима» и говорит об этом
|
||||
|
||||
@@ -13,6 +13,40 @@ upgrade` идёт по записям снизу вверх от версии п
|
||||
|
||||
---
|
||||
|
||||
## Версия 8 — 2026-08-09
|
||||
|
||||
Канон отпустил каталог задач. Плагин `av-dev-pm` расколот на `av-dev-docs`
|
||||
(документы) и `av-dev-tasks` (учёт работ), и каждый теперь ставится сам по себе.
|
||||
Пока владелец был один, `docs/tasks/` числился слотом канона: `docs.py` требовал
|
||||
каталог, звал внутрь чужой скрипт и выдавал его дрейф за свой, а настройки задач
|
||||
жили ключом `tasks` в `docs/.pm.json`. Для проекта, поставившего только документы,
|
||||
всё это — отказ на ровном месте: задач он не ведёт, и требовать их не за что.
|
||||
|
||||
**Что изменилось.** Каталог задач канону не принадлежит; канон резервирует ему
|
||||
место в `docs/` и внутрь не смотрит. `docs.py` больше не проверяет согласованность
|
||||
задач вовсе — это делает `tasks.py` сам, командой своего плагина. Дом настроек
|
||||
каталога задач — `<каталог задач>/.tasks.json`; ключ `tasks` в `docs/.pm.json`
|
||||
читается, только пока своего файла нет, и об этом говорится замечанием.
|
||||
|
||||
**Что удалено.** Проверка `check_tasks` из `docs.py` и ключ `"tasks"` из скелета
|
||||
`docs/.pm.json`.
|
||||
|
||||
**Что сделать проекту.**
|
||||
|
||||
1. Перенести настройки задач: содержимое ключа `"tasks"` из `docs/.pm.json` — в
|
||||
`docs/tasks/.tasks.json` тем же объектом. Ключа в проекте нет (имена файлов
|
||||
и заголовков умолчательные) — переносить нечего, шаг пропускается.
|
||||
2. Удалить ключ `"tasks"` из `docs/.pm.json` после переноса. Оставленный он не
|
||||
читается, и `tasks.py` скажет об этом замечанием на каждом прогоне.
|
||||
3. Проверить, что согласованность задач по-прежнему кто-то гоняет: раньше её
|
||||
тянул за собой `docs.py check`, теперь — только `tasks.py check`. **Если в
|
||||
гейте проекта стоял один `docs.py`, добавить туда второй шаг** — иначе дрейф
|
||||
индексов перестанет ловиться молча, и это самая вероятная потеря на этом
|
||||
повышении.
|
||||
4. Установить оба плагина, если нужны оба: `av-dev-docs` и `av-dev-tasks`
|
||||
вместо прежнего `av-dev-pm`. Прежний из `enabledPlugins` убрать.
|
||||
5. `docs/.pm.json`: `"canon": 8`.
|
||||
|
||||
## Версия 7 — 2026-08-07
|
||||
|
||||
`openspec/` был предпосылкой, о которой канон говорил, но за которой не следил.
|
||||
|
||||
@@ -501,11 +501,10 @@ rules:
|
||||
|
||||
```json
|
||||
{
|
||||
"canon": 7
|
||||
"canon": 8
|
||||
}
|
||||
```
|
||||
|
||||
Плюс `"migrations": "<путь>"`, если есть БД. Ключ `"tasks"` заводится **только**
|
||||
когда имя файла или заголовка отличается от умолчания (`{"backlog":
|
||||
"INDEX.md"}`); секций беклога в нём нет — их дом заголовки `##` индекса. Состав
|
||||
ключей — [canon.md](canon.md).
|
||||
Плюс `"migrations": "<путь>"`, если есть БД. Ключа `"tasks"` здесь **нет**:
|
||||
настройки каталога задач переехали в свой файл `<каталог задач>/.tasks.json`,
|
||||
потому что ведёт их другой плагин. Состав ключей — [canon.md](canon.md).
|
||||
|
||||
Reference in New Issue
Block a user