Третий заход по находкам ревью — то, что старше темы 78 и тянулось с тем 74–77. Оснований у развилки три во всех местах: конвейер называл два, а устав триажа, контракт находок, сценарий решения и журнал — три. Там же сказано, чем третье отличается: по первым двум оркестратор урезает изменение до остатка, третье отменяет одобрение и возвращает на чекпоинт. Вопросы проекта по темам достались проходам, которые эти темы закрывают: review-code, review-specs и review-autotests получили обязанность отвечать дословно и строку в блоке покрытия. Прежде конвейер обещал их каждому проходу, а знал о них только приёмник тем. Глубокое ревью приведено к уставам, которые зовёт: глубина у проходов разная — доказательство у тех двоих, что держат машину, разбор у architecture и code; у триажа три вызывающих, а не два режима, и потолка в 7 пунктов там нет. Версия раскладки поднята до 5 с записью журнала: скелет docs/review.md потерял подраздел «Триггеры метки» ещё темой 77, а миграции проектам никто не дал. Сняты остатки меток в task-track и в config-skeleton, уезжающем в чужой проект. Перечень осей досчитал три оси: глубина темы, разметка действия, род правки. Журнал — тема 81.
267 lines
23 KiB
Markdown
267 lines
23 KiB
Markdown
# Журнал версий раскладки
|
||
|
||
Одна запись на версию. Проект знает свою версию из ключа `version` в
|
||
`.av-dev.toml`; операция `upgrade` скилла `av-dev:canon` идёт по записям
|
||
снизу вверх от версии проекта до текущей и делает то, что в них названо.
|
||
|
||
Правило записи: **что добавилось, что переехало, что удалено, что сделать
|
||
проекту**. Без последнего пункта запись бесполезна — по ней и работает
|
||
`upgrade`.
|
||
|
||
Версия — целое число. Обратной совместимости нет: есть «приведён» и «не
|
||
приведён». Версия **одна на всю раскладку** — и на документы канона, и на
|
||
каталог задач: ведёт их один плагин, и второе число означало бы только вопрос,
|
||
по какому журналу повышать.
|
||
|
||
**До слияния журналов было два**, и нумерация в них своя:
|
||
[changelog-before-merge.md](changelog-before-merge.md) — канон документов,
|
||
версии 1–14; [changelog-tasks-before-merge.md](changelog-tasks-before-merge.md) —
|
||
формат задач, версия 1. Оба **закрыты и не переписаны**: адрес, верный на день
|
||
записи, там и остался. Проект, отставший от канона 14, идёт сперва по ним, а
|
||
потом по этому журналу — порядок назван в записи 1.
|
||
|
||
---
|
||
|
||
## Версия 5 — 2026-08-23
|
||
|
||
**Метка задачи снята из процесса целиком**, и вместе с ней — подраздел «Триггеры
|
||
метки» в `docs/review.md`. Состав прогона ревью стал постоянным: он один и тот же
|
||
на всякой задаче, выбирать нечего, и признаки, по которым метка поднималась,
|
||
перестали что-либо решать. На месте подраздела — **«Когда звать глубокое ревью»**:
|
||
те же наблюдения проекта, но адресованные другому решению — звать ли
|
||
`av-dev:code-deep-review` по области кода.
|
||
|
||
**Что переехало в проекте.** Скелет `docs/review.md`, раздел настройки конвейера:
|
||
подраздел «Триггеры метки» заменён подразделом «Когда звать глубокое ревью» —
|
||
**двумя списками**: области, которые смотрят целиком (узлы с частым возвратом,
|
||
места с историей инцидентов, код под дорогое решение), и **необратимое здесь** —
|
||
что в этом проекте после мерджа не откатывается обратной правкой. Второй список
|
||
работает и в цикле задачи: находка в таком месте уходит человеку развилкой, а не
|
||
чинится молча. Само правило — в [canon.md](canon.md), раздел `review.md`.
|
||
|
||
**Что сделать проекту.**
|
||
|
||
1. **Переписать подраздел в `docs/review.md`.** Заголовок «Триггеры метки»
|
||
становится «Когда звать глубокое ревью», содержимое — два списка выше.
|
||
Признаки, годные только для выбора метки («больше N файлов», «затронуто больше
|
||
одного слоя»), выбрасываются: состава прогона они не меняют. Что из прежнего
|
||
списка называло **необратимое место** — переносится во второй список дословно.
|
||
2. **Пройти по документам** — `grep -rniE "small|medium|large|метк" docs/`.
|
||
Найденное в `review.md`, `conventions/` и `adr/` правится по смыслу: описание
|
||
прошлого решения остаётся как свидетельство, действующая инструкция —
|
||
переписывается или снимается.
|
||
3. **Поднять версию** — `docs.py bump`, последним шагом.
|
||
4. `docs.py check` — до отсутствия дрейфа.
|
||
|
||
**Чего делать не надо.** Заводить ключ `[docs] healthcheck_last` руками: он
|
||
необязательный и появится сам первым прогоном `av-dev:doc-healthcheck`. Править
|
||
прошлые записи журналов и архивные change — тоже: метка, стоявшая в них, верна
|
||
как свидетельство о том дне.
|
||
|
||
---
|
||
|
||
## Версия 4 — 2026-08-13
|
||
|
||
Слово **провенанс** снято из словаря языка проектных текстов и заменено русским.
|
||
Оно стояло в закрытом списке своих терминов с оговоркой «„источник“ рядом
|
||
называет саму запись, а не свойство» — верной, но доказывающей лишь то, что не
|
||
годится одно русское слово. Годятся два, и по смыслу они разные: **происхождение**
|
||
у числа (чем и при каких условиях получено) и **откуда** у вопроса или находки
|
||
(кто нашёл, каким проходом, из какой записи журнала).
|
||
|
||
**Что переехало в проекте.** Скелет `docs/review.md`, подраздел «Вопросы по
|
||
темам»: форма вопроса записана как `<тема>: <вопрос> (<откуда>)` вместо
|
||
`(<провенанс>)`. Само правило — в [canon.md](canon.md), раздел `review.*`;
|
||
требование к числам `research/` не изменилось по существу, изменилось слово.
|
||
|
||
**Что сделать проекту.**
|
||
|
||
1. **Поправить форму в `docs/review.md`** — строка «Форма: `<тема>: <вопрос>
|
||
(<провенанс>)`» становится «Форма: `<тема>: <вопрос> (<откуда>)`». Уже
|
||
записанные вопросы переписывать не надо: слово стояло в шаблоне, а не в них.
|
||
2. **Пройти по документам** — `grep -rn "провенанс" docs/`. Найденное в
|
||
`research/` и в `adr/` заменяется на **происхождение** (речь о числе) или на
|
||
**откуда** (речь о том, из чего вопрос или находка выросли). Ничего не
|
||
нашлось — шаг закрыт строкой, это обычный исход.
|
||
3. **Поднять версию** — `docs.py bump`, последним шагом.
|
||
4. `docs.py check` — до отсутствия дрейфа.
|
||
|
||
**Чего делать не надо.** Править прошлые записи журналов и архивные change:
|
||
слово, верное на день записи, остаётся верным как свидетельство.
|
||
|
||
---
|
||
|
||
## Версия 3 — 2026-08-13
|
||
|
||
Тип записи `goal` и индекс `ROADMAP.md` упразднены; у проекта появилась
|
||
**стадия** — `build` (беклог это план стройки, порядок строк значит зависимость)
|
||
или `support` (очередь правок, порядок значит важность).
|
||
|
||
Цель была зонтиком над параллельными направлениями — она нужна там, где список
|
||
работ нельзя выстроить в один порядок. У проекта, который ведёт один человек,
|
||
такого не бывает, и роадмап при этом наполовину дублировал беклог («чего ещё не
|
||
умеет» = «что осталось в списке»), а вторую половину («что уже умеет») отвечают
|
||
`openspec/specs/` и `git log` индекса.
|
||
|
||
**Что переехало.** Индекс остался один — `BACKLOG.md`. Поле меты `Секция` стало
|
||
`Категория`; теги `goal:<слаг>`, `decomposed` и раздел `Завершение` упразднены;
|
||
команды `list --goal`, `edit --goal`, `edit --section` и ключи `[tasks] roadmap`,
|
||
`[tasks] completion_heading` — тоже. Появились ключ `[tasks] stage`, команда
|
||
`tasks.py stage` и флаги `init --stage`, `adopt scan --stage`.
|
||
|
||
**Что сделать проекту. Порядок шагов обязателен**, и первый шаг — не команда:
|
||
пока в `[tasks]` лежит упразднённый ключ, **любая** подкоманда `tasks.py`
|
||
отвечает кодом 3 и работать нечем.
|
||
|
||
1. **Вычистить конфиг руками.** Из секции `[tasks]` в `.av-dev.toml` удалить
|
||
ключи `roadmap` (или `plan`) и `completion_heading`. Каждый из них — код 3 на
|
||
любой команде, и названы они здесь оба: второй легко пропустить, потому что
|
||
его упразднение не видно по имени файла.
|
||
2. **Удалить `tasks/ROADMAP.md`.** Секция `Готово` уходит вместе с ним и **не
|
||
переносится**: «что приложение умеет» отвечают спеки, «когда это появилось» —
|
||
`git log` беклога. Проект без `openspec/specs/` теряет здесь единственный
|
||
связный перечень достигнутого — если он нужен, сохрани его сам до удаления
|
||
(документом проекта, не задачами).
|
||
3. **Прогнать `tasks.py check --fix`.** Он снимет теги `goal:<слаг>` и
|
||
`decomposed`, переименует поле `Секция` → `Категория` и перепишет старую
|
||
форму меты — **в том числе у самих записей типа `goal`**. Записи `goal` при
|
||
этом останутся: во что превращается цель, машина не решает и говорит
|
||
`НЕОДНОЗНАЧНО`.
|
||
4. **Разобрать цели поштучно.** У каждой два исхода, и выбирает человек: она
|
||
становится задачей (`edit <слаг> --type feature|fix|chore|research`) либо
|
||
уходит (`close <слаг> --reason …`). Строки в беклоге у неё нет — её жильём
|
||
был роадмап, — и `edit --type` заведёт её сам, в первую секцию и в конец,
|
||
сказав об этом; место назначь потом. Раздел `Завершение` в теле переехавшей
|
||
записи **удали руками**: схеме нового типа он не принадлежит, и `check`
|
||
оставит о нём замечание. Задачи, носившие тег цели, живут дальше сами по
|
||
себе — разбирать их не нужно.
|
||
5. **Объявить стадию** — `tasks.py stage build` или `tasks.py stage support`.
|
||
Приложение ещё строится и список работ линеен по зависимости — `build`;
|
||
работает и правится точечно — `support`. Без ключа `check` отказывает: порядок
|
||
строк нечем прочитать.
|
||
|
||
**Объявление беклог не трогает** — ни секций, ни файлов: оно называет то, что
|
||
уже верно. Поэтому проекту с несколькими полками, объявляющему `build`,
|
||
команда откажет и назовёт выход: слить полки самому (`move <слаг> --section
|
||
<куда> --reason …`), потому что порядок строк в слитом списке знает только
|
||
человек. Флаг `--sections` при объявлении не принимается — он для **смены**
|
||
стадии, где сливать просят явно.
|
||
6. **Поправить шапку `BACKLOG.md`.** Абзац про стадию теперь размечен парой
|
||
`<!-- стадия -->` … `<!-- /стадия -->`, и по нему `check` сверяет шапку с
|
||
конфигом. В беклоге, заведённом до этой версии, разметки нет — `stage` об
|
||
этом скажет. Возьми готовый абзац из свежего каталога (`tasks.py init` во
|
||
временном месте) или напиши сам: он объясняет, что значит порядок строк, и
|
||
читают вместо документации именно его.
|
||
7. **Поднять версию** — `docs.py bump`. Последним шагом. Он двигает **одну**
|
||
запись за раз: отставшему на две записи проекту зовётся дважды, следом за
|
||
шагами каждой.
|
||
8. `docs.py check` и `tasks.py check --dir <каталог задач>` — до отсутствия
|
||
дрейфа.
|
||
|
||
**Проект, не прошедший записи 1 и 2, начинает с этой.** Их собственные шаги
|
||
велят гонять `tasks.py check` до зелёного, а он на упразднённом ключе отвечает
|
||
кодом 3 — то есть пройти их сегодня нельзя, не сделав шаг 1 отсюда. Записи от
|
||
этого не переписываются: порядок между ними прежний, добавлено одно условие
|
||
входа.
|
||
|
||
---
|
||
|
||
## Версия 2 — 2026-08-13
|
||
|
||
Скилл `doc-canon` стал `canon`: префикс называл материал (`doc-`), а скилл
|
||
занят не материалом, а **формой** — раскладкой всех частей проекта и общим
|
||
повышением версии. Ни один файл проекта от этого не переехал; сменились **путь к
|
||
скрипту** и **имя вызова**, а оба живут в проекте: первый — строкой гейта, второй
|
||
— в `CLAUDE.md` и в записях задач.
|
||
|
||
**Что переехало в вызовах.** `av-dev:doc-canon` → `av-dev:canon`. Прочие имена не
|
||
тронуты.
|
||
|
||
**Что сделать проекту.**
|
||
|
||
1. **Поправить шаг гейта.** Путь к `docs.py` сменился вместе с именем каталога
|
||
скилла: `skills/doc-canon/scripts/docs.py` →
|
||
`skills/canon/scripts/docs.py`. Шаг, который не нашёл скрипт, обязан
|
||
краснеть, а не пропускаться, — проверь, что он краснеет.
|
||
2. **Поправить свои вызовы скилла** — `grep -rn "doc-canon" --exclude-dir=.git .`
|
||
по проекту целиком: имя встречается в `CLAUDE.md`, в `Taskfile`, в записях
|
||
задач и в документах канона. Прежнее полное имя не разрешится вовсе.
|
||
3. **Поднять версию** — `docs.py bump`. Последним шагом.
|
||
4. `docs.py check` и `tasks.py check --dir <каталог задач>` — до отсутствия
|
||
дрейфа.
|
||
|
||
**Проект, не прошедший запись 1, переименовывает дважды подряд** — `skills/canon/`
|
||
→ `skills/doc-canon/` записью 1 и обратно этой. Порядок записей от этого не
|
||
меняется: каждая исполняется на том состоянии, которое оставила предыдущая, и
|
||
прошлая запись под новое имя не переписывается.
|
||
|
||
---
|
||
|
||
## Версия 1 — 2026-08-13
|
||
|
||
Три плагина — `av-dev-docs`, `av-dev-tasks` и `av-dev-code` — слились в один,
|
||
`av-dev`. Раскол делался под раздельную установку: проект мог взять учёт работ
|
||
без документов канона или конвейер без обоих. Практика посылку не подтвердила —
|
||
подмножество не понадобилось ни разу, — а платился раскол помеченными копиями
|
||
общих правил и веткой «плагина нет» на каждый вызов соседа.
|
||
|
||
**Что переехало в проекте.** Служебных файла было два, стал один:
|
||
|
||
| Было | Стало |
|
||
| --- | --- |
|
||
| `docs/.docs.json`, ключ `canon` | `.av-dev.toml` в корне, ключ `version` |
|
||
| `docs/.docs.json`, ключ `migrations` | `.av-dev.toml`, секция `[docs]` |
|
||
| `<каталог задач>/.tasks.json`, ключ `tasks` | тот же `version`: версия теперь одна |
|
||
| `<каталог задач>/.tasks.json`, имена частей | `.av-dev.toml`, секция `[tasks]` |
|
||
|
||
Корень выбран потому, что он есть у обоих: и у проекта без `docs/`, и у проекта
|
||
без каталога задач. Формат TOML — ради комментариев: файл лежит в репозитории
|
||
проекта, и назначение числа читают из него самого, а не из документации плагина.
|
||
|
||
**Что переехало в вызовах.** Имена скиллов сменили пространство имён и получили
|
||
префикс по прежнему плагину: `av-dev-docs:canon` → `av-dev:doc-canon`,
|
||
`av-dev-docs:init` → `av-dev:doc-init`, `av-dev-docs:docs` → `av-dev:doc-sync`,
|
||
`av-dev-docs:healthcheck` → `av-dev:doc-healthcheck`, `av-dev-tasks:tasks` →
|
||
`av-dev:task-track`, `av-dev-tasks:groom` → `av-dev:task-groom`,
|
||
`av-dev-code:openspec` → `av-dev:code-openspec`, `av-dev-code:resolve` →
|
||
`av-dev:code-resolve`, `av-dev-code:review` → `av-dev:code-review`.
|
||
|
||
**Что сделать проекту.**
|
||
|
||
1. **Отставшим сперва прежние журналы.** Версия канона в `docs/.docs.json`
|
||
меньше 14 — пройди записи до 14 по
|
||
[changelog-before-merge.md](changelog-before-merge.md), и только потом эту.
|
||
Иначе повышение объявит приведённым то, чего никто не делал.
|
||
2. **Завести `.av-dev.toml`** в корне репозитория: `version = 1`, секция
|
||
`[docs]` с `migrations`, если ключ был, секция `[tasks]` с `dir` и теми
|
||
именами частей, которые в `.tasks.json` отличались от умолчаний. Комментарии
|
||
пиши свои — файл читает человек.
|
||
3. **Удалить `docs/.docs.json` и `<каталог задач>/.tasks.json`.** Прежние имена
|
||
не читаются: два дома для одной версии расходятся молча. Пока старые файлы на
|
||
месте, `docs.py check` и `tasks.py check` называют это прежней раскладкой.
|
||
4. **Переставить плагины.** `av-dev-docs`, `av-dev-tasks` и `av-dev-code`
|
||
удалить, `av-dev` поставить — команды в README репозитория плагинов.
|
||
5. **Поправить гейт проекта.** Пути к `docs.py`, `tasks.py` и `openspec.py`
|
||
сменились вместе с именами каталогов скиллов: `skills/canon/` →
|
||
`skills/doc-canon/`, `skills/tasks/` → `skills/task-track/`,
|
||
`skills/openspec/` → `skills/code-openspec/`. Шаг, который не нашёл скрипт,
|
||
обязан краснеть, а не пропускаться, — проверь, что он краснеет.
|
||
6. **Поправить свои вызовы скиллов** — в `CLAUDE.md`, в `Taskfile`, в записях
|
||
задач: короткое имя разрешится в проектную копию, а прежнее полное не
|
||
разрешится вовсе.
|
||
7. **Найти, где проект читает служебный файл сам.** Шаг гейта, скрипт, шаблон —
|
||
что угодно, что брало значение из `docs/.docs.json`, чтобы не заводить факту
|
||
второй дом. Такое чтение переезжает на `.av-dev.toml` и на `tomllib` вместо
|
||
`json`: `python3 -c 'import tomllib; print(tomllib.load(open(".av-dev.toml","rb"))["docs"]["migrations"])'`.
|
||
Ищется командой `grep -rn "\.docs\.json\|\.tasks\.json" --exclude-dir=.git .`
|
||
— по проекту целиком, а не по документам: на первом же живом переезде это
|
||
нашлось в `Taskfile.yml`, и нашёл это гейт, а не человек.
|
||
8. **Поднять версию** — `docs.py bump`. Последним шагом: число объявляет
|
||
пройденными шаги журнала, и раньше времени поднятое врёт.
|
||
9. `docs.py check` и `tasks.py check --dir <каталог задач>` — до отсутствия
|
||
дрейфа.
|
||
|
||
**Чего делать не надо.** Переписывать прошлые записи журналов под новые имена.
|
||
Они описывают состояния, которые были, и адрес, верный на день записи, остаётся
|
||
верным как свидетельство.
|