словарь, манифесты, README: одно слово — одна вещь, одно описание — один дом
- «готовность» значила и «запись можно брать», и «что считается сделанным»; второй смысл стал «определением сделанного» — своё же правило про занятое слово запрещало это прямо - «пайплайн» жил в 24 местах вне журналов при том, что DECISIONS фиксирует его уход «целиком»; рабочее имя — конвейер - «чекпоинт» в review значил стадию и проход, в resolve — остановку человеку; слово оставлено за остановкой - у описания плагина было два дома, и три из четырёх уже разошлись. Сведены, и класс закрыт машиной: frontmatter.py сверяет plugin.json с marketplace, гейт разбужен на *.json - README врал про односторонние зависимости и терял healthcheck на диаграмме - перечень агентов в REMAINING отстал на два поколения Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,17 +8,17 @@
|
|||||||
{
|
{
|
||||||
"name": "av-dev-docs",
|
"name": "av-dev-docs",
|
||||||
"source": "./av-dev-docs",
|
"source": "./av-dev-docs",
|
||||||
"description": "Документация проекта: канон раскладки docs/ и CLAUDE.md, роли документов, правило единственного дома. check / adopt / upgrade со скриптом docs.py, старт проекта интервью по брифу, ведение содержимого по ходу разработки, healthcheck — сверка документов между собой и с кодом судом двух агентов. Ничего не выполняет сам и никакого пайплайна не требует."
|
"description": "Документация проекта: канон раскладки (CLAUDE.md плюс docs/ — паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), роли документов и правило единственного дома. Три операции одной машиной сравнения — check, adopt, upgrade — со скриптом docs.py; заведение нового проекта интервью по брифу; ведение содержимого по ходу разработки: синк после сделанной задачи, ADR промоутом из архивного design.md, записка разведки, запись дефекта в журнал ревью. Смысловое, чего скрипт не видит, судит скилл healthcheck двумя агентами разом — doc-consistency (документы между собой и с openspec) и doc-code-drift (факты против кода); язык документов вычитывает агент doc-wording. Задач не ведёт — это плагин av-dev-tasks, и он опционален."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "av-dev-tasks",
|
"name": "av-dev-tasks",
|
||||||
"source": "./av-dev-tasks",
|
"source": "./av-dev-tasks",
|
||||||
"description": "Задачи и цели каталогом markdown-файлов, у каждой записи тип, и тип задаёт её схему. Приоритет — порядок строк в беклоге, расставляет его скилл груминга. Проверка согласованности скриптом tasks.py. Задача выполняется чем угодно: пайплайна плагин не требует и сам его не зовёт."
|
"description": "Задачи и цели каталогом markdown-файлов: одна запись — файл в items/ плюс строка ровно в одном индексе, у записи тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение из диалога с фильтром и дедупом, разбор находок ревью в задачи, декомпозиция на независимо полезные части, гигиена полей, согласованность индексов скриптом tasks.py. Приоритет — явный порядок строк в беклоге, и расставляет его скилл groom: интерактивный разбор на два вопроса, что сейчас самое важное и что перестало быть важным. Готовность записи к работе проверяет команда ready. Записи вычитывают два прохода: task-form (форма записи) и task-wording (язык). Канон документов ведёт плагин av-dev-docs, он опционален. Задач не выполняет — этим занимается конвейер проекта."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "av-dev-code",
|
"name": "av-dev-code",
|
||||||
"source": "./av-dev-code",
|
"source": "./av-dev-code",
|
||||||
"description": "Решение одной задачи от постановки до закрытия: цикл SDD с чекпоинтом объяснения после ревью дизайна, у исследовательской задачи — ещё и чекпоинт вариантов до первого требования. Конвейер ревью с обязательным триажем. Требует OpenSpec. Задача принимается и обычным текстом; плагины av-dev-docs и av-dev-tasks опциональны — первый даёт документы канона для проходов ревью, второй учёт задач, без них прогон деградирует поразрядно и говорит об этом."
|
"description": "Решение одной задачи от постановки до закрытия скиллом resolve — полный цикл Spec Driven Development с двумя плановыми остановками: чекпоинт вариантов у исследовательской задачи и чекпоинт с объяснением человеческим языком после ревью дизайна у всякой. Между ними работа идёт без согласований. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. Требует OpenSpec и сам его заводит скиллом openspec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "av-dev-git",
|
"name": "av-dev-git",
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
ли документы между собой и с кодом. Зовёт двух агентов на весь канон разом —
|
ли документы между собой и с кодом. Зовёт двух агентов на весь канон разом —
|
||||||
`doc-consistency` (документы между собой и с openspec) и `doc-code-drift`
|
`doc-consistency` (документы между собой и с openspec) и `doc-code-drift`
|
||||||
(факты против кода) — и разбирает урожай порциями. Дорого, поэтому не на
|
(факты против кода) — и разбирает урожай порциями. Дорого, поэтому не на
|
||||||
каждой задаче; язык документов вычитывает отдельный агент `doc-wording`;
|
каждой задаче. Язык документов вычитывает отдельный агент `doc-wording`, и
|
||||||
|
зовут его не отсюда, а те, кто только что писал текст: `docs`, `init` и
|
||||||
|
`canon`;
|
||||||
- `docs` — содержимое канона по ходу разработки: ADR из архивного
|
- `docs` — содержимое канона по ходу разработки: ADR из архивного
|
||||||
`design.md`, промоут конвенций, запись в разведку и журнал ревью, чистка
|
`design.md`, промоут конвенций, запись в разведку и журнал ревью, чистка
|
||||||
архитектуры.
|
архитектуры.
|
||||||
@@ -61,7 +63,9 @@
|
|||||||
Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена
|
Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена
|
||||||
**скилов** внутри — короткие. Вызов выходит вида `/av-dev-<плагин>:<скилл>`.
|
**скилов** внутри — короткие. Вызов выходит вида `/av-dev-<плагин>:<скилл>`.
|
||||||
|
|
||||||
Кто кого зовёт (стрелка — вызов через пространство имён, не импорт):
|
Кто кого зовёт. Сплошная стрелка — вызов скилла через пространство имён, не
|
||||||
|
импорт; пунктир — совет позвать, а не вызов. Агенты-проходы в графе не показаны:
|
||||||
|
их зовут скиллы, названные выше.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TB
|
flowchart TB
|
||||||
@@ -75,6 +79,7 @@ flowchart TB
|
|||||||
init["init"]
|
init["init"]
|
||||||
canon["canon"]
|
canon["canon"]
|
||||||
docs["docs"]
|
docs["docs"]
|
||||||
|
hc["healthcheck"]
|
||||||
end
|
end
|
||||||
subgraph tasksp["av-dev-tasks — учёт работ"]
|
subgraph tasksp["av-dev-tasks — учёт работ"]
|
||||||
direction LR
|
direction LR
|
||||||
@@ -84,6 +89,11 @@ flowchart TB
|
|||||||
init --> osp
|
init --> osp
|
||||||
canon --> tasks
|
canon --> tasks
|
||||||
canon --> osp
|
canon --> osp
|
||||||
|
canon --> hc
|
||||||
|
hc --> tasks
|
||||||
|
docs --> rp
|
||||||
|
rp --> tasks
|
||||||
|
groom -.-> hc
|
||||||
opsx["opsx:* — внешний плагин:<br/>explore, propose, apply, archive"]
|
opsx["opsx:* — внешний плагин:<br/>explore, propose, apply, archive"]
|
||||||
git["av-dev-git: commit"]
|
git["av-dev-git: commit"]
|
||||||
|
|
||||||
@@ -93,9 +103,14 @@ flowchart TB
|
|||||||
tp --> tasks
|
tp --> tasks
|
||||||
```
|
```
|
||||||
|
|
||||||
Зависимости **односторонние: `av-dev-code` знает про `av-dev-docs` и
|
Зависимости **взаимные, но каждая мягкая**. `av-dev-code` зовёт обоих соседей;
|
||||||
`av-dev-tasks`, обратно — нет.** Между собой эти двое тоже не связаны жёстко:
|
обратные вызовы тоже есть — `av-dev-docs:init` и `av-dev-docs:canon` заводят
|
||||||
каждый работает без другого. Как именно зовут соседа и что делают, когда вызов не
|
OpenSpec скиллом `av-dev-code:openspec`, `av-dev-docs:docs` берёт у
|
||||||
|
`av-dev-code:review` форму записи журнала дефектов и процедуру промоута,
|
||||||
|
`av-dev-docs:canon` и `av-dev-docs:healthcheck` зовут `av-dev-tasks:tasks`.
|
||||||
|
**Мягкая** значит, что у любого вызова есть ветка «не разрешился»: соседа в
|
||||||
|
проекте нет — вызывающий называет строкой, чего теперь не делает никто, и работу
|
||||||
|
не останавливает. Как именно зовут соседа и что делают, когда вызов не
|
||||||
разрешился, — `shared/plugin-boundary.md`: правило нужно большинству скиллов, и
|
разрешился, — `shared/plugin-boundary.md`: правило нужно большинству скиллов, и
|
||||||
ни один плагин им не владеет. То, что нужно нескольким дословно — граница
|
ни один плагин им не владеет. То, что нужно нескольким дословно — граница
|
||||||
плагинов, язык проектных текстов, словарь сопровождения, — живёт домом в
|
плагинов, язык проектных текстов, словарь сопровождения, — живёт домом в
|
||||||
@@ -292,17 +307,17 @@ uv run pyrefly check # типы
|
|||||||
линтеров, и любой сторонний импорт у него не разрешается. Список запретов —
|
линтеров, и любой сторонний импорт у него не разрешается. Список запретов —
|
||||||
не перечень мира, настоящий страж второй.
|
не перечень мира, настоящий страж второй.
|
||||||
|
|
||||||
## Проверка фронтматтеров
|
## Проверка фронтматтеров и описаний плагинов
|
||||||
|
|
||||||
Фронтматтер читает не человек, а загрузчик: по `name` он разрешает вызов, по
|
Фронтматтер читает не человек, а загрузчик: по `name` он разрешает вызов, по
|
||||||
`description` решает, звать ли скилл вообще. **Ошибка здесь не выглядит
|
`description` решает, звать ли скилл вообще. **Ошибка здесь не выглядит
|
||||||
ошибкой** — тем же способом, что и в диаграммах.
|
ошибкой** — тем же способом, что и в диаграммах.
|
||||||
|
|
||||||
```
|
```
|
||||||
uv run python scripts/frontmatter.py # 0 в порядке, 1 расхождение, 3 не тот каталог
|
python3 scripts/frontmatter.py # 0 в порядке, 1 расхождение, 3 не тот каталог
|
||||||
```
|
```
|
||||||
|
|
||||||
Ловится три класса:
|
Ловится четыре класса:
|
||||||
|
|
||||||
- **двоеточие с пробелом в описании без кавычек.** Для YAML `: ` внутри
|
- **двоеточие с пробелом в описании без кавычек.** Для YAML `: ` внутри
|
||||||
простого скаляра начинает вложенное отображение, так что «конвейер ревью: гейт,
|
простого скаляра начинает вложенное отображение, так что «конвейер ревью: гейт,
|
||||||
@@ -317,7 +332,13 @@ uv run python scripts/frontmatter.py # 0 в порядке, 1 расхожд
|
|||||||
[review/SKILL.md](av-dev-code/skills/review/SKILL.md),
|
[review/SKILL.md](av-dev-code/skills/review/SKILL.md),
|
||||||
разделе «Модель по проходу», здесь только её механизация. Держаться вниманием
|
разделе «Модель по проходу», здесь только её механизация. Держаться вниманием
|
||||||
правило не может: цвет ставится один раз при заведении charter'а, а модель
|
правило не может: цвет ставится один раз при заведении charter'а, а модель
|
||||||
потом меняется калибровкой.
|
потом меняется калибровкой;
|
||||||
|
- **описание плагина, разошедшееся между манифестами.** У описания два дома:
|
||||||
|
`<плагин>/.claude-plugin/plugin.json` показывает его установленному плагину,
|
||||||
|
корневой `.claude-plugin/marketplace.json` — тому, кто выбирает, ставить ли.
|
||||||
|
Правят обычно один, и разойтись они успели уже трижды из четырёх. `copies.py`
|
||||||
|
этот класс не берёт: он смотрит markdown, а манифест — json. Отсюда и `*.json`
|
||||||
|
в глобе задачи гейта.
|
||||||
|
|
||||||
## Проверка копий правил
|
## Проверка копий правил
|
||||||
|
|
||||||
@@ -326,7 +347,7 @@ uv run python scripts/frontmatter.py # 0 в порядке, 1 расхожд
|
|||||||
говорить. Значит копия допустима, но **дословная и помеченная**:
|
говорить. Значит копия допустима, но **дословная и помеченная**:
|
||||||
|
|
||||||
```
|
```
|
||||||
uv run python scripts/copies.py # 0 сошлось, 1 расхождение, 2 разметка, 3 не тот каталог
|
python3 scripts/copies.py # 0 сошлось, 1 расхождение, 2 разметка, 3 не тот каталог
|
||||||
```
|
```
|
||||||
|
|
||||||
Разметка — HTML-комментарии, невидимые в отрендеренном markdown:
|
Разметка — HTML-комментарии, невидимые в отрендеренном markdown:
|
||||||
@@ -429,8 +450,8 @@ python3 scripts/addresses.py # весь репозиторий
|
|||||||
правдоподобно, диff показывает разумную строку, а рендер падает.
|
правдоподобно, диff показывает разумную строку, а рендер падает.
|
||||||
|
|
||||||
```
|
```
|
||||||
uv run python scripts/diagrams.py # весь репозиторий
|
python3 scripts/diagrams.py # весь репозиторий
|
||||||
uv run python scripts/diagrams.py A.md B.md # только названные файлы
|
python3 scripts/diagrams.py A.md B.md # только названные файлы
|
||||||
# 0 рендерятся, 1 нет, 3 нет mermaid-cli
|
# 0 рендерятся, 1 нет, 3 нет mermaid-cli
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -461,7 +482,7 @@ lefthook run pre-commit # прогнать руками, не коммитя
|
|||||||
|
|
||||||
| Проверка | Когда идёт | Что смотрит | Сколько |
|
| Проверка | Когда идёт | Что смотрит | Сколько |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| фронтматтеры | правка `*.md` | весь репозиторий | миллисекунды |
|
| фронтматтеры | правка `*.md` или `*.json` | весь репозиторий | миллисекунды |
|
||||||
| копии правил | правка `*.md` | весь репозиторий | миллисекунды |
|
| копии правил | правка `*.md` | весь репозиторий | миллисекунды |
|
||||||
| адреса документов | **каждый коммит** | весь репозиторий | ~0.07 с |
|
| адреса документов | **каждый коммит** | весь репозиторий | ~0.07 с |
|
||||||
| диаграммы | правка `*.md` | staged-файлы | ~1 с на файл |
|
| диаграммы | правка `*.md` | staged-файлы | ~1 с на файл |
|
||||||
@@ -472,8 +493,8 @@ Glob разводит две половины: коммит, трогающий
|
|||||||
диаграмм, а коммит в документы не гоняет линтеры.
|
диаграмм, а коммит в документы не гоняет линтеры.
|
||||||
|
|
||||||
**Судятся staged-файлы, а не рабочее дерево** — гейт обязан проверять то, что
|
**Судятся staged-файлы, а не рабочее дерево** — гейт обязан проверять то, что
|
||||||
уедет в историю, а не то, что случайно лежит рядом на диске. Исключений два, и
|
уедет в историю, а не то, что случайно лежит рядом на диске. Исключений три, и
|
||||||
три, и все про существо, а не про удобство: `copies.py` сверяет копию с домом, а
|
все про существо, а не про удобство: `copies.py` сверяет копию с домом, а
|
||||||
дом лежит в другом файле, которого в индексе может не быть (список staged дал бы
|
дом лежит в другом файле, которого в индексе может не быть (список staged дал бы
|
||||||
«копии дословны» ровно там, где правка дома их и разошлась); `frontmatter.py`
|
«копии дословны» ровно там, где правка дома их и разошлась); `frontmatter.py`
|
||||||
обходит весь репозиторий за сотые доли секунды — экономить тут нечего;
|
обходит весь репозиторий за сотые доли секунды — экономить тут нечего;
|
||||||
|
|||||||
+10
-8
@@ -81,10 +81,11 @@ check` сверяет версию, но не то, что миграционн
|
|||||||
только её последствия.
|
только её последствия.
|
||||||
|
|
||||||
**Не выродились ли «границы покрытия» в шаблон.** Строка «что смотрели и чего не
|
**Не выродились ли «границы покрытия» в шаблон.** Строка «что смотрели и чего не
|
||||||
смотрели» обязательна в докладе `check`, `adopt`, интейка, штурма, сессии,
|
смотрели» обязательна в докладе `check`, `adopt`, интейка, штурма и всех пяти
|
||||||
спринта и всех четырёх агентов — семь и больше раз за сессию, и проверить её
|
агентов канона и задач (`doc-consistency`, `doc-code-drift`, `doc-wording`,
|
||||||
исполнение некому: приёмщик и исполнитель одно лицо (`groom/SKILL.md`,
|
`task-form`, `task-wording`) — девять мест, и проверить её исполнение некому:
|
||||||
«Стимулы»). Выродившаяся строка **хуже отсутствия**: доклад выглядит проверенным.
|
приёмщик и исполнитель одно лицо (`groom/SKILL.md`, «Стимулы»). Выродившаяся
|
||||||
|
строка **хуже отсутствия**: доклад выглядит проверенным.
|
||||||
|
|
||||||
Приём не правится: это гипотеза об износе, а не находка, и менять работающее по
|
Приём не правится: это гипотеза об износе, а не находка, и менять работающее по
|
||||||
догадке дороже. **Наблюдение к первой обкатке на живом проекте:** если в трёх
|
догадке дороже. **Наблюдение к первой обкатке на живом проекте:** если в трёх
|
||||||
@@ -93,10 +94,11 @@ check` сверяет версию, но не то, что миграционн
|
|||||||
|
|
||||||
**Форма ADR при пересмотре решения.** Парный статус («старая запись получает
|
**Форма ADR при пересмотре решения.** Парный статус («старая запись получает
|
||||||
`заменено на`») судит агент `doc-consistency` — правило 6 его устава. Охват был
|
`заменено на`») судит агент `doc-consistency` — правило 6 его устава. Охват был
|
||||||
открытым вопросом, пока агент зовётся пачкой, отобранной работой; переезд вызова
|
открытым вопросом, пока агент звался пачкой, отобранной работой; переезд вызова
|
||||||
на сессию с пачкой «весь канон» его снял. Остаётся зазор в спринт и отсутствие
|
в `av-dev-docs:healthcheck` с пачкой «весь канон» его снял. Остаётся зазор до
|
||||||
механической проверки — то есть пересмотр, сделанный сегодня, судится на
|
ближайшего прогона `healthcheck` и отсутствие механической проверки — то есть
|
||||||
ближайшей сессии, а не в момент правки.
|
пересмотр, сделанный сегодня, судится тогда, когда позовут сверку, а не в момент
|
||||||
|
правки.
|
||||||
|
|
||||||
## Известные пределы — приняты, чинить не планируется
|
## Известные пределы — приняты, чинить не планируется
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "av-dev-code",
|
"name": "av-dev-code",
|
||||||
"description": "Решение одной задачи от постановки до закрытия скиллом resolve — полный цикл Spec Driven Development с двумя плановыми остановками: чекпоинт вариантов у исследовательской задачи и чекпоинт с объяснением человеческим языком после ревью дизайна у всякой. Между ними работа идёт без согласований. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом, независимой реализацией и обязательным триажем. Требует OpenSpec и сам его заводит скиллом openspec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой.",
|
"description": "Решение одной задачи от постановки до закрытия скиллом resolve — полный цикл Spec Driven Development с двумя плановыми остановками: чекпоинт вариантов у исследовательской задачи и чекпоинт с объяснением человеческим языком после ревью дизайна у всякой. Между ними работа идёт без согласований. Плюс конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом и обязательным триажем. Требует OpenSpec и сам его заводит скиллом openspec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Anton Vakhrushev",
|
"name": "Anton Vakhrushev",
|
||||||
"email": "anwinged@gmail.com"
|
"email": "anwinged@gmail.com"
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ OpenSpec заводит человек командой выше.
|
|||||||
|
|
||||||
## Чего этот скилл не делает
|
## Чего этот скилл не делает
|
||||||
|
|
||||||
- **Не пишет спеки и предложения.** Это `opsx:propose` и пайплайн задачи.
|
- **Не пишет спеки и предложения.** Это `opsx:propose` и конвейер задачи.
|
||||||
- **Не ведёт документы канона** — их дом плагин `av-dev-docs`, и адреса в
|
- **Не ведёт документы канона** — их дом плагин `av-dev-docs`, и адреса в
|
||||||
`context` только на них ссылаются.
|
`context` только на них ссылаются.
|
||||||
- **Не чинит расхождение формы с версией OpenSpec в проекте.** Оно чинится в
|
- **Не чинит расхождение формы с версией OpenSpec в проекте.** Оно чинится в
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ description: "Решить одну задачу от постановки до
|
|||||||
шаги 2, 6 и 8, шаг Р2 разведки, проход `review-specs` и ревью дизайна (они
|
шаги 2, 6 и 8, шаг Р2 разведки, проход `review-specs` и ревью дизайна (они
|
||||||
завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
завязаны на `openspec/changes/<id>/specs/*/spec.md` и на
|
||||||
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
`openspec validate --strict`). **Проект без OpenSpec этим скиллом не ведётся** —
|
||||||
подключай OpenSpec, а не вырождай цикл: ветка деградации здесь не пишется,
|
подключай OpenSpec, а не вырождай цикл; почему ветка деградации здесь не
|
||||||
потому что непроверенная ветка деградации хуже честного отказа. Заводить
|
пишется, сказано в `av-dev-code:review`, раздел «Предпосылки», и дом у этого
|
||||||
руками не надо: каталог и настройку в `config.yaml` делает скилл
|
довода там. Заводить руками не надо: каталог и настройку в `config.yaml`
|
||||||
`av-dev-code:openspec`.
|
делает скилл `av-dev-code:openspec`.
|
||||||
- **Проектные копии этих скиллов и агентов удаляются при установке плагина**
|
- **Проектные копии этих скиллов и агентов удаляются при установке плагина**
|
||||||
(`.claude/skills/` — голые имена `resolve`, `review`, а у проектов прошлого
|
(`.claude/skills/` — голые имена `resolve`, `review`, а у проектов прошлого
|
||||||
поколения ещё `task-pipeline`, `review-pipeline`, `task-batch`, и с префиксом
|
поколения ещё `task-pipeline`, `review-pipeline`, `task-batch`, и с префиксом
|
||||||
@@ -212,9 +212,9 @@ flowchart TD
|
|||||||
- **Форматом задач.** Индексы руками не правятся, путь к скрипту учёта не
|
- **Форматом задач.** Индексы руками не правятся, путь к скрипту учёта не
|
||||||
выдумывается: этим владеет `av-dev-tasks:tasks` (шаг 11). Закрытие — работа
|
выдумывается: этим владеет `av-dev-tasks:tasks` (шаг 11). Закрытие — работа
|
||||||
этого скилла, и это осознанное решение с названной ценой: **приёмщик и
|
этого скилла, и это осознанное решение с названной ценой: **приёмщик и
|
||||||
исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на сессии
|
исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на
|
||||||
возвращает задачу `reopen` с причиной, а доклад по критериям приёмки становится
|
груминге (`av-dev-tasks:groom`) возвращает задачу `reopen` с причиной, а доклад
|
||||||
единственным, по чему приёмка вообще возможна.
|
по критериям приёмки становится единственным, по чему приёмка вообще возможна.
|
||||||
- **Заведением задач из урожая ревью.** Отложенные находки отдаются **списком**;
|
- **Заведением задач из урожая ревью.** Отложенные находки отдаются **списком**;
|
||||||
превращать их в задачи — работа `av-dev-tasks:tasks`, у него на этот вход
|
превращать их в задачи — работа `av-dev-tasks:tasks`, у него на этот вход
|
||||||
отдельный сценарий «задачи из ревью и аудита». Плагина нет — урожай остаётся
|
отдельный сценарий «задачи из ревью и аудита». Плагина нет — урожай остаётся
|
||||||
@@ -226,7 +226,7 @@ flowchart TD
|
|||||||
|
|
||||||
Ровно четыре, и каждый обязан быть назван в докладе прямо:
|
Ровно четыре, и каждый обязан быть назван в докладе прямо:
|
||||||
|
|
||||||
- **сделана** — определение готовности выполнено целиком;
|
- **сделана** — определение сделанного выполнено целиком;
|
||||||
- **не доведена** — с причиной и с записанным вопросом; что именно сделано и до
|
- **не доведена** — с причиной и с записанным вопросом; что именно сделано и до
|
||||||
какой границы, названо явно. Сюда же попадает чекпоинт, на котором человек
|
какой границы, названо явно. Сюда же попадает чекпоинт, на котором человек
|
||||||
решение не одобрил;
|
решение не одобрил;
|
||||||
@@ -236,7 +236,7 @@ flowchart TD
|
|||||||
по названному адресу, кода задача не потребовала. Это полноправный исход, а не
|
по названному адресу, кода задача не потребовала. Это полноправный исход, а не
|
||||||
недоведённая работа.
|
недоведённая работа.
|
||||||
|
|
||||||
## Определение готовности
|
## Определение сделанного
|
||||||
|
|
||||||
Задача сделана, когда верно всё:
|
Задача сделана, когда верно всё:
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ flowchart TD
|
|||||||
| `large` | `specs`, `rubric`, `architecture` + вопрос автору о трёх формах решения |
|
| `large` | `specs`, `rubric`, `architecture` + вопрос автору о трёх формах решения |
|
||||||
|
|
||||||
`review-specs` в режиме «дизайн ДО кода» идёт **на каждой задаче**: это самый
|
`review-specs` в режиме «дизайн ДО кода» идёт **на каждой задаче**: это самый
|
||||||
дешёвый чекпоинт конвейера, и он ловит то, что на готовом коде уже не чинят.
|
дешёвый проход конвейера, и он ловит то, что на готовом коде уже не чинят.
|
||||||
Остальные включаются меткой, потому что стадия стоит на каждой задаче и каждый
|
Остальные включаются меткой, потому что стадия стоит на каждой задаче и каждый
|
||||||
лишний проход здесь умножается на число задач.
|
лишний проход здесь умножается на число задач.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: review
|
name: review
|
||||||
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после propose: агент review-scope выводит размер и сложность, из их максимума — метка, и раздаёт темы проходам обеих стадий. Метка правит и ревью дизайна (small — только specs; medium — плюс rubric; large — плюс architecture), и ревью кода (small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе). Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона av-dev-docs. Вызывается из скилла resolve — двумя чекпоинтами: ревью дизайна до кода и ревью кода после apply."
|
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после propose: агент review-scope выводит размер и сложность, из их максимума — метка, и раздаёт темы проходам обеих стадий. Метка правит и ревью дизайна (small — только specs; medium — плюс rubric; large — плюс architecture), и ревью кода (small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе). Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона av-dev-docs. Вызывается из скилла resolve — двумя стадиями: ревью дизайна до кода и ревью кода после apply."
|
||||||
---
|
---
|
||||||
|
|
||||||
# Конвейер ревью
|
# Конвейер ревью
|
||||||
@@ -44,7 +44,7 @@ description: "Конвейер ревью изменения, устроенны
|
|||||||
|
|
||||||
- **OpenSpec — жёсткая предпосылка, а не опция.** Ревью дизайна, проход
|
- **OpenSpec — жёсткая предпосылка, а не опция.** Ревью дизайна, проход
|
||||||
`review-specs` и
|
`review-specs` и
|
||||||
вызывающий пайплайн задачи завязаны на дельта-спеки
|
вызывающий скилл `av-dev-code:resolve` завязаны на дельта-спеки
|
||||||
(`openspec/changes/<id>/specs/*/spec.md`), на актуальные спеки
|
(`openspec/changes/<id>/specs/*/spec.md`), на актуальные спеки
|
||||||
(`openspec/specs/`) и на `openspec validate --strict`. В проекте без OpenSpec
|
(`openspec/specs/`) и на `openspec validate --strict`. В проекте без OpenSpec
|
||||||
шаги, зовущие `opsx:explore` / `opsx:propose` / `opsx:apply` / `opsx:archive`,
|
шаги, зовущие `opsx:explore` / `opsx:propose` / `opsx:apply` / `opsx:archive`,
|
||||||
@@ -624,7 +624,7 @@ flowchart TD
|
|||||||
|
|
||||||
**План живёт в контексте прогона задачи и на диск не пишется.** Файл-план был бы
|
**План живёт в контексте прогона задачи и на диск не пишется.** Файл-план был бы
|
||||||
четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, жил бы
|
четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, жил бы
|
||||||
дольше задачи и расходился бы с ней молча. Прервали пайплайн — разметка
|
дольше задачи и расходился бы с ней молча. Прервали прогон задачи — разметка
|
||||||
повторяется; это самый дешёвый проход конвейера, и платить за его вечность
|
повторяется; это самый дешёвый проход конвейера, и платить за его вечность
|
||||||
дороже, чем перезапустить.
|
дороже, чем перезапустить.
|
||||||
|
|
||||||
@@ -848,7 +848,7 @@ Recall темы `conventions` равен длине конвенций прое
|
|||||||
|
|
||||||
## Ревью дизайна — до кода
|
## Ревью дизайна — до кода
|
||||||
|
|
||||||
Запускается на первом чекпоинте ревью (шаг 4 скилла
|
Запускается на первой стадии ревью (шаг 4 скилла
|
||||||
`av-dev-code:resolve`), когда change уже имеет `proposal.md` и
|
`av-dev-code:resolve`), когда change уже имеет `proposal.md` и
|
||||||
дельта-спеки, но кода ещё нет. Разметка задачи к этому моменту уже прошла — она
|
дельта-спеки, но кода ещё нет. Разметка задачи к этому моменту уже прошла — она
|
||||||
шагом раньше, и метка известна.
|
шагом раньше, и метка известна.
|
||||||
@@ -864,7 +864,7 @@ Recall темы `conventions` равен длине конвенций прое
|
|||||||
| `large` — крупное или незнакомое | `specs`, `rubric`, `architecture` + вопрос автору | **3** |
|
| `large` — крупное или незнакомое | `specs`, `rubric`, `architecture` + вопрос автору | **3** |
|
||||||
|
|
||||||
- **всегда** — `review-specs` в режиме «дизайн ДО кода». Дельта-спеки сверяются
|
- **всегда** — `review-specs` в режиме «дизайн ДО кода». Дельта-спеки сверяются
|
||||||
на каждой задаче: это самый дешёвый чекпоинт конвейера, и он ловит то, что на
|
на каждой задаче: это самый дешёвый проход конвейера, и он ловит то, что на
|
||||||
готовом коде уже не чинят;
|
готовом коде уже не чинят;
|
||||||
- **со `medium`** — `review-rubric`: рубрика на задуманный узел, по ней же
|
- **со `medium`** — `review-rubric`: рубрика на задуманный узел, по ней же
|
||||||
разбирается дельта-спека, а сами пункты уезжают приёмочными критериями в
|
разбирается дельта-спека, а сами пункты уезжают приёмочными критериями в
|
||||||
@@ -886,14 +886,15 @@ Recall темы `conventions` равен длине конвенций прое
|
|||||||
отвечается «нет» ещё до запуска. Держать её ниже `large` значит платить за
|
отвечается «нет» ещё до запуска. Держать её ниже `large` значит платить за
|
||||||
предсказуемый ответ на каждой задаче.
|
предсказуемый ответ на каждой задаче.
|
||||||
|
|
||||||
Причина меток — арифметика, а не экономия на осторожности. Чекпоинт стоит
|
Причина меток — арифметика, а не экономия на осторожности. Стадия стоит
|
||||||
**на каждой задаче**, поэтому каждый проход здесь умножается на число задач, и при
|
**на каждой задаче**, поэтому каждый проход здесь умножается на число задач, и при
|
||||||
мелкой нарезке это самая большая статья конвейера.
|
мелкой нарезке это самая большая статья конвейера.
|
||||||
|
|
||||||
**Граф этой стадии свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
**Граф этой стадии свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
||||||
нечего; метка уже названа разметкой задачи; машину не держит ни один проход;
|
нечего; метка уже названа разметкой задачи; машину не держит ни один проход;
|
||||||
сток — не триаж, а шаг пайплайна задачи, где замечания отрабатываются правкой
|
сток — не триаж, а шаг скилла `av-dev-code:resolve`, где замечания
|
||||||
спек. Триаж здесь не нужен: находок единицы, и каждая либо правит спеку, либо
|
отрабатываются правкой спек. Триаж здесь не нужен: находок единицы, и каждая
|
||||||
|
либо правит спеку, либо
|
||||||
становится развилкой.
|
становится развилкой.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
@@ -904,7 +905,7 @@ flowchart TD
|
|||||||
rubric["rubric → приёмочные критерии в tasks.md"]
|
rubric["rubric → приёмочные критерии в tasks.md"]
|
||||||
arch["architecture на предложении"]
|
arch["architecture на предложении"]
|
||||||
author["вопрос автору: три формы решения и компромисс каждой"]
|
author["вопрос автору: три формы решения и компромисс каждой"]
|
||||||
fix["шаг пайплайна: правка спек, развилки — вопросом в запись"]
|
fix["шаг resolve: правка спек, развилки — вопросом в запись"]
|
||||||
|
|
||||||
plan --> proposal
|
plan --> proposal
|
||||||
proposal --> specs
|
proposal --> specs
|
||||||
@@ -938,7 +939,7 @@ flowchart TD
|
|||||||
|
|
||||||
- Оркестратор чинит помеченное `Действие: инлайн` и **не логирует мелочь**.
|
- Оркестратор чинит помеченное `Действие: инлайн` и **не логирует мелочь**.
|
||||||
- `Действие: развилка` — вопросом с вариантами и ценой каждого туда, где проект
|
- `Действие: развилка` — вопросом с вариантами и ценой каждого туда, где проект
|
||||||
держит вопросы (это знает вызвавший пайплайн, а не конвейер). Оркестратор не
|
держит вопросы (это знает вызвавший скилл, а не конвейер ревью). Оркестратор не
|
||||||
останавливается: он урезает изменение до остатка и доводит его.
|
останавливается: он урезает изменение до остатка и доводит его.
|
||||||
- Находка не для этого мерджа, но реальная (отложенный `major`, развилка,
|
- Находка не для этого мерджа, но реальная (отложенный `major`, развилка,
|
||||||
решённая «потом»), — не теряется, но **и не заводится здесь**. Конвейер отдаёт
|
решённая «потом»), — не теряется, но **и не заводится здесь**. Конвейер отдаёт
|
||||||
@@ -960,10 +961,10 @@ flowchart TD
|
|||||||
заведено: нулевой урожай при непустом отчёте виден сразу.
|
заведено: нулевой урожай при непустом отчёте виден сразу.
|
||||||
**Вместе с изменением он и переезжает:** после `opsx:archive` его адрес —
|
**Вместе с изменением он и переезжает:** после `opsx:archive` его адрес —
|
||||||
`openspec/changes/archive/<id>/review/`. Кто ищет отчёт после архивации
|
`openspec/changes/archive/<id>/review/`. Кто ищет отчёт после архивации
|
||||||
(приёмщик на сессии, разбор дефекта), смотрит **оба** пути; «отчёта нет»
|
(приёмщик на груминге `av-dev-tasks:groom`, разбор дефекта), смотрит **оба**
|
||||||
объявляется, только когда пуст и архивный, иначе самый дорогой сценарий
|
пути; «отчёта нет» объявляется, только когда пуст и архивный, иначе самый
|
||||||
«состав ревью неизвестен, гоняем заново» срабатывает на каждой доведённой
|
дорогой сценарий «состав ревью неизвестен, гоняем заново» срабатывает на
|
||||||
задаче.
|
каждой доведённой задаче.
|
||||||
|
|
||||||
## Честный предел
|
## Честный предел
|
||||||
|
|
||||||
@@ -1030,7 +1031,7 @@ flowchart TD
|
|||||||
сверкой и доказательством лежит весь класс дефектов, который виден только
|
сверкой и доказательством лежит весь класс дефектов, который виден только
|
||||||
построенным путём, — и он проверяется на 5–10% задач.
|
построенным путём, — и он проверяется на 5–10% задач.
|
||||||
|
|
||||||
Это сознательная сделка, а не пробел в устройстве: цес меткой `large` платится на
|
Это сознательная сделка, а не пробел в устройстве: цена метки `large` платится на
|
||||||
каждой задаче, а окупается на немногих. Проверяется сделка не рассуждением, а
|
каждой задаче, а окупается на немногих. Проверяется сделка не рассуждением, а
|
||||||
журналом дефектов: если класс, который ловят только меряющие проходы, начал
|
журналом дефектов: если класс, который ловят только меряющие проходы, начал
|
||||||
всплывать после мерджа — метку выбирают слишком низко.
|
всплывать после мерджа — метку выбирают слишком низко.
|
||||||
|
|||||||
@@ -132,5 +132,6 @@
|
|||||||
на диск и на СУБД» экономит обязательный вопрос. Отсутствие строки — не факт,
|
на диск и на СУБД» экономит обязательный вопрос. Отсутствие строки — не факт,
|
||||||
а пробел, и его надо назвать в границах покрытия.
|
а пробел, и его надо назвать в границах покрытия.
|
||||||
- **Свойство, ставшее правилом линтера, из конвенций удалено** и лежит в
|
- **Свойство, ставшее правилом линтера, из конвенций удалено** и лежит в
|
||||||
перечне механизированного в `docs/conventions/README.md`. Проверять его
|
перечне механизированного — в `docs/conventions/README.md`, если конвенции
|
||||||
проходом — тратить внимание на уже проверенное.
|
каталогом, и отдельным разделом `docs/conventions.md`, если файлом. Проверять
|
||||||
|
его проходом — тратить внимание на уже проверенное.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ flowchart TD
|
|||||||
no["промоуту не подлежит:<br/>место одно — комментарий в коде;<br/>вкусовщина — вон на триаже;<br/>нужен рантайм — в журнал ревью"]
|
no["промоуту не подлежит:<br/>место одно — комментарий в коде;<br/>вкусовщина — вон на триаже;<br/>нужен рантайм — в журнал ревью"]
|
||||||
conv["конвенция:<br/>проверяемое свойство + какой проход нашёл"]
|
conv["конвенция:<br/>проверяемое свойство + какой проход нашёл"]
|
||||||
rule["правило линтера, запретитель,<br/>тест-сканер или анализатор"]
|
rule["правило линтера, запретитель,<br/>тест-сканер или анализатор"]
|
||||||
clean["шаг 3: формулировка удалена из конвенций,<br/>строка — в conventions/README.md"]
|
clean["шаг 3: формулировка удалена из конвенций,<br/>строка — в перечень механизированного"]
|
||||||
|
|
||||||
f --> cond
|
f --> cond
|
||||||
cond -->|нет| no
|
cond -->|нет| no
|
||||||
@@ -85,8 +85,9 @@ flowchart TD
|
|||||||
- из файла конвенций убирается формулировка правила; остаётся, если нужно, одна
|
- из файла конвенций убирается формулировка правила; остаётся, если нужно, одна
|
||||||
строка «проверяется линтером `<имя>`» — но только там, где без неё раздел
|
строка «проверяется линтером `<имя>`» — но только там, где без неё раздел
|
||||||
теряет связность;
|
теряет связность;
|
||||||
- правило переезжает в **перечень механизированного в
|
- правило переезжает в **перечень механизированного в доме конвенций**
|
||||||
`docs/conventions/README.md`** — со ссылкой на место механизации: конфиг
|
(`docs/conventions/README.md` у каталога, отдельный раздел
|
||||||
|
`docs/conventions.md` у файла) — со ссылкой на место механизации: конфиг
|
||||||
линтера, собственный анализатор, тест-сканер исходников. Не названное место
|
линтера, собственный анализатор, тест-сканер исходников. Не названное место
|
||||||
означает, что проход будет добросовестно проверять уже проверенное;
|
означает, что проход будет добросовестно проверять уже проверенное;
|
||||||
- из контекста инструмента спек убирается дубль, если он там был.
|
- из контекста инструмента спек убирается дубль, если он там был.
|
||||||
|
|||||||
@@ -180,6 +180,14 @@ color: yellow
|
|||||||
|
|
||||||
## Доклад
|
## Доклад
|
||||||
|
|
||||||
|
**Форма параллельна дому `вычитка-доклад` (`shared/language.md`), но копией не
|
||||||
|
является, и маркера здесь нет намеренно.** Копию того дома везут проходы вычитки
|
||||||
|
— `doc-wording` и `task-wording`; у судьи утверждений расходится каждое поле:
|
||||||
|
находка стоит на **паре** документов, а не на одном, несёт **дом по канону** и не
|
||||||
|
несёт «почему», а границы покрытия считают документы и спрашивают про спеки и
|
||||||
|
архив изменений, а не про термины. Одинаков только порядок разделов, и сверять
|
||||||
|
машиной в нём нечего.
|
||||||
|
|
||||||
Находки по одной, в порядке важности: прямые противоречия → факт в двух домах →
|
Находки по одной, в порядке важности: прямые противоречия → факт в двух домах →
|
||||||
поведение в обзоре → ADR и провенанс → пустые слоты. Первые ломают решения,
|
поведение в обзоре → ADR и провенанс → пустые слоты. Первые ломают решения,
|
||||||
которые по документам принимают; последние — только цену чтения.
|
которые по документам принимают; последние — только цену чтения.
|
||||||
|
|||||||
@@ -219,7 +219,8 @@ capability), `openspec/config.yaml`.
|
|||||||
каталога показывает только `tasks.py check`. Позвал на шаге 5 скилл задач —
|
каталога показывает только `tasks.py check`. Позвал на шаге 5 скилл задач —
|
||||||
его отчёт идёт в доклад отдельной строкой, и пункт «задачи без цели» в нём
|
его отчёт идёт в доклад отдельной строкой, и пункт «задачи без цели» в нём
|
||||||
зелёным не станет: цели не сочиняются адаптацией (запрет записан у того, кто
|
зелёным не станет: цели не сочиняются адаптацией (запрет записан у того, кто
|
||||||
ведёт задачи), их проставляет человек порциями переоценки на первой сессии.
|
ведёт задачи), их проставляет человек порциями переоценки на первом груминге —
|
||||||
|
скилл `av-dev-tasks:groom`.
|
||||||
|
|
||||||
### 5. Объяви переходное состояние
|
### 5. Объяви переходное состояние
|
||||||
|
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ severity стоит здесь, а не выводится каждым прох
|
|||||||
- **Что считается сломанным** — какая красная проверка обгоняет развитие,
|
- **Что считается сломанным** — какая красная проверка обгоняет развитие,
|
||||||
то есть останавливает текущую работу:
|
то есть останавливает текущую работу:
|
||||||
- **Ориентир по размеру порции:** своё число, если замерялось
|
- **Ориентир по размеру порции:** своё число, если замерялось
|
||||||
- **Что такое «сделана»:** пайплайн проекта пройден + критерии приёмки проверены
|
- **Что такое «сделана»:** конвейер проекта пройден + критерии приёмки проверены
|
||||||
поимённо
|
поимённо
|
||||||
|
|
||||||
## Язык
|
## Язык
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ description: Вести содержимое документов канона
|
|||||||
Определение канона и роли документов — [канон](../canon/references/canon.md),
|
Определение канона и роли документов — [канон](../canon/references/canon.md),
|
||||||
здесь не пересказывается.
|
здесь не пересказывается.
|
||||||
|
|
||||||
Главный вызывающий — **шаг синка документации в пайплайне задачи**. Пайплайн
|
Главный вызывающий — **шаг синка документации в конвейере задачи**. Конвейер
|
||||||
живёт в другом плагине и зовёт этот скилл по имени; проект без пайплайна ведёт
|
живёт в другом плагине и зовёт этот скилл по имени; проект без конвейера ведёт
|
||||||
документацию тем же скиллом вручную.
|
документацию тем же скиллом вручную.
|
||||||
|
|
||||||
## Правило, из которого всё следует
|
## Правило, из которого всё следует
|
||||||
@@ -55,7 +55,7 @@ description: Вести содержимое документов канона
|
|||||||
- passport, security, conventions, review — не требуется: изменение внутреннее
|
- passport, security, conventions, review — не требуется: изменение внутреннее
|
||||||
```
|
```
|
||||||
|
|
||||||
## Сверка — не здесь, а на сессии
|
## Сверка — не здесь, а в `av-dev-docs:healthcheck`
|
||||||
|
|
||||||
Синк правит документы поодиночке, а расходятся они **между собой**: факт,
|
Синк правит документы поодиночке, а расходятся они **между собой**: факт,
|
||||||
дописанный в `architecture.md`, уже живёт в `CLAUDE.md`; периметр в
|
дописанный в `architecture.md`, уже живёт в `CLAUDE.md`; периметр в
|
||||||
@@ -80,8 +80,8 @@ description: Вести содержимое документов канона
|
|||||||
**Язык правленого вычитывается на синке, и зовёшь агента `doc-wording` ты.**
|
**Язык правленого вычитывается на синке, и зовёшь агента `doc-wording` ты.**
|
||||||
Довод обратный доводу про судей: он читает **только названную пачку**, стоит
|
Довод обратный доводу про судей: он читает **только названную пачку**, стоит
|
||||||
дёшево и ищет ровно то, что портится в момент письма, — залог, оценку без факта,
|
дёшево и ищет ровно то, что портится в момент письма, — залог, оценку без факта,
|
||||||
жаргон, термин без ввода. Ждать сессии здесь нечего: через месяц никто уже не
|
жаргон, термин без ввода. Ждать `healthcheck` здесь нечего: через месяц никто уже
|
||||||
помнит, какую фразу имел в виду автор.
|
не помнит, какую фразу имел в виду автор.
|
||||||
|
|
||||||
Позови его **последним шагом синка**, отдав список файлов, которых чек-лист
|
Позови его **последним шагом синка**, отдав список файлов, которых чек-лист
|
||||||
коснулся, — и назови этот список в промпте: по нему же он судит, известен ли
|
коснулся, — и назови этот список в промпте: по нему же он судит, известен ли
|
||||||
@@ -181,7 +181,7 @@ description: Вести содержимое документов канона
|
|||||||
Твоя часть на синке: **дефект пишется сразу**, а не «потом, когда починим».
|
Твоя часть на синке: **дефект пишется сразу**, а не «потом, когда починим».
|
||||||
Со временем теряется не факт, а то, почему дефект не поймали, — единственное,
|
Со временем теряется не факт, а то, почему дефект не поймали, — единственное,
|
||||||
ради чего журнал есть. И решение сузить проверки (перестали звать проход, понизили
|
ради чего журнал есть. И решение сузить проверки (перестали звать проход, понизили
|
||||||
метка) обязано попасть в раздел настройки, а не остаться в отчёте ревью.
|
метку) обязано попасть в раздел настройки, а не остаться в отчёте ревью.
|
||||||
|
|
||||||
## Промоут в конвенции
|
## Промоут в конвенции
|
||||||
|
|
||||||
|
|||||||
@@ -130,9 +130,12 @@ check` и его скрипт; здесь начинается там, где к
|
|||||||
|
|
||||||
- **Не проверяет раскладку, версию и ссылки** — это `canon check`, там машина.
|
- **Не проверяет раскладку, версию и ссылки** — это `canon check`, там машина.
|
||||||
- **Не судит язык** документов: залог, англицизмы, жаргон, термин без дома — это
|
- **Не судит язык** документов: залог, англицизмы, жаргон, термин без дома — это
|
||||||
агент `doc-wording`, и зовут его отдельно, по пачке правленных документов. У
|
агент `doc-wording`, и зовут его отдельно, по пачке правленных документов.
|
||||||
него другой ритм: он нужен там, где текст только что писали, а не там, где он
|
Звонящие у него названные — последний шаг синка в `av-dev-docs:docs`, шаг 9
|
||||||
год лежал. Оркестровать его нечем — он один и работает по названному списку.
|
`av-dev-docs:init` и шаг вычитки в обоих режимах `canon`, — просто ни один из
|
||||||
|
них не здесь. У него другой ритм: он нужен там, где текст только что писали, а
|
||||||
|
не там, где он год лежал. Оркестровать его нечем — он один и работает по
|
||||||
|
названному списку.
|
||||||
- **Не правит документы за агентов** — они возвращают формулировки, решение
|
- **Не правит документы за агентов** — они возвращают формулировки, решение
|
||||||
подставить принимает человек или ты по его правилу.
|
подставить принимает человек или ты по его правилу.
|
||||||
- **Не заводит задачи** — этим владеет `av-dev-tasks:tasks`.
|
- **Не заводит задачи** — этим владеет `av-dev-tasks:tasks`.
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ description: "Завести новый проект — сессия вопро
|
|||||||
|
|
||||||
- Содержимое канона по ходу разработки ведёт скилл `docs`.
|
- Содержимое канона по ходу разработки ведёт скилл `docs`.
|
||||||
- Раскладку проверяет `canon check`.
|
- Раскладку проверяет `canon check`.
|
||||||
- Первую задачу берёт пайплайн проекта; `architecture.md` и `conventions/`
|
- Первую задачу берёт конвейер проекта; `architecture.md` и `conventions/`
|
||||||
наполняются его шагом синка, а не заранее.
|
наполняются его шагом синка, а не заранее.
|
||||||
|
|
||||||
## Чего этот скилл не делает
|
## Чего этот скилл не делает
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "av-dev-tasks",
|
"name": "av-dev-tasks",
|
||||||
"description": "Задачи и цели каталогом markdown-файлов: одна запись — файл в items/ плюс строка ровно в одном индексе, у записи тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение из диалога с фильтром и дедупом, разбор находок ревью в задачи, декомпозиция на независимо полезные части, гигиена полей, согласованность индексов скриптом tasks.py. Приоритет — явный порядок строк в беклоге, и расставляет его скилл groom: интерактивный разбор на два вопроса, что сейчас самое важное и что перестало быть важным. Готовность записи к работе проверяет команда ready. Записи вычитывают два прохода: task-form (форма записи) и task-wording (язык). Канон документов ведёт плагин av-dev-docs, он опционален. Задач не выполняет — этим занимается пайплайн проекта.",
|
"description": "Задачи и цели каталогом markdown-файлов: одна запись — файл в items/ плюс строка ровно в одном индексе, у записи тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение из диалога с фильтром и дедупом, разбор находок ревью в задачи, декомпозиция на независимо полезные части, гигиена полей, согласованность индексов скриптом tasks.py. Приоритет — явный порядок строк в беклоге, и расставляет его скилл groom: интерактивный разбор на два вопроса, что сейчас самое важное и что перестало быть важным. Готовность записи к работе проверяет команда ready. Записи вычитывают два прохода: task-form (форма записи) и task-wording (язык). Канон документов ведёт плагин av-dev-docs, он опционален. Задач не выполняет — этим занимается конвейер проекта.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Anton Vakhrushev",
|
"name": "Anton Vakhrushev",
|
||||||
"email": "anwinged@gmail.com"
|
"email": "anwinged@gmail.com"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: groom
|
name: groom
|
||||||
description: "Груминг беклога — интерактивный разбор, отвечающий на два вопроса: что сейчас самое важное и что перестало быть важным. Ответ записывается порядком строк в беклоге: первая строка — то, что делают следующим. Разбирает накопившиеся вопросы, переоценивает задачи порциями по 5–8 (сделано попутно, отменено решением, слилось с соседней, подешевело, разрослось, стало сырьём), закрывает отжившее с причиной и расставляет очередь. Использовать, когда просят разобрать беклог, расставить приоритеты, решить «что делать дальше», провести груминг или переоценку, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое записей — скилл tasks; выполнение задачи — пайплайн проекта."
|
description: "Груминг беклога — интерактивный разбор, отвечающий на два вопроса: что сейчас самое важное и что перестало быть важным. Ответ записывается порядком строк в беклоге: первая строка — то, что делают следующим. Разбирает накопившиеся вопросы, переоценивает задачи порциями по 5–8 (сделано попутно, отменено решением, слилось с соседней, подешевело, разрослось, стало сырьём), закрывает отжившее с причиной и расставляет очередь. Использовать, когда просят разобрать беклог, расставить приоритеты, решить «что делать дальше», провести груминг или переоценку, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое записей — скилл tasks; выполнение задачи — конвейер проекта."
|
||||||
---
|
---
|
||||||
|
|
||||||
# Груминг: что важно, что перестало
|
# Груминг: что важно, что перестало
|
||||||
@@ -22,7 +22,7 @@ description: "Груминг беклога — интерактивный ра
|
|||||||
без вопросов и показывается списком.
|
без вопросов и показывается списком.
|
||||||
|
|
||||||
Форматом и содержимым записей владеет скилл `tasks` — груминг зовёт его
|
Форматом и содержимым записей владеет скилл `tasks` — груминг зовёт его
|
||||||
операции, а не правит файлы руками. Выполнением задачи — пайплайн проекта.
|
операции, а не правит файлы руками. Выполнением задачи — конвейер проекта.
|
||||||
|
|
||||||
## Три правила, из которых всё следует
|
## Три правила, из которых всё следует
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ description: "Груминг беклога — интерактивный ра
|
|||||||
|
|
||||||
**Отличать вопрос от застревания.** Правило про остаток принадлежит управлению
|
**Отличать вопрос от застревания.** Правило про остаток принадлежит управлению
|
||||||
задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не
|
задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не
|
||||||
исполнения. **Ниже канонический текст; пайплайн проекта на него ссылается, а не
|
исполнения. **Ниже канонический текст; конвейер проекта на него ссылается, а не
|
||||||
пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются
|
пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются
|
||||||
незаметно, потому что расхождение видно только на редком входе.
|
незаметно, потому что расхождение видно только на редком входе.
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ description: Ведение задач и целей как каталога mar
|
|||||||
|
|
||||||
Чем он **не** владеет: **очередью** — что делать следующим и что перестало быть
|
Чем он **не** владеет: **очередью** — что делать следующим и что перестало быть
|
||||||
важным, решает скилл `groom`, а этот скилл лишь даёт ему операции; и выполнением
|
важным, решает скилл `groom`, а этот скилл лишь даёт ему операции; и выполнением
|
||||||
задачи — это пайплайн проекта.
|
задачи — это конвейер проекта.
|
||||||
|
|
||||||
## Шесть правил, из которых всё следует
|
## Шесть правил, из которых всё следует
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ stateDiagram-v2
|
|||||||
**напоминает** — беклог, заведённый до появления типа, законен, и переоформлять
|
**напоминает** — беклог, заведённый до появления типа, законен, и переоформлять
|
||||||
его «заодно» здесь не просят.
|
его «заодно» здесь не просят.
|
||||||
|
|
||||||
**Тип не выбирает метку ревью и вообще ничего не предписывает пайплайну.**
|
**Тип не выбирает метку ревью и вообще ничего не предписывает конвейеру.**
|
||||||
Профиль выбирается по факту изменения, а не по типу задачи: `chore` бывает
|
Профиль выбирается по факту изменения, а не по типу задачи: `chore` бывает
|
||||||
миграцией схемы, `fix` — правкой публичного контракта. Правило «предписание
|
миграцией схемы, `fix` — правкой публичного контракта. Правило «предписание
|
||||||
процесса в теле задачи снимается» типом не отменяется, а подтверждается: он
|
процесса в теле задачи снимается» типом не отменяется, а подтверждается: он
|
||||||
@@ -664,7 +664,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
|||||||
|
|
||||||
### Вызов из другого плагина
|
### Вызов из другого плагина
|
||||||
|
|
||||||
`$CLAUDE_PLUGIN_ROOT` раскрывается **только внутри своего плагина**: пайплайн
|
`$CLAUDE_PLUGIN_ROOT` раскрывается **только внутри своего плагина**: конвейер
|
||||||
задачи, конвейер ревью и любой другой чужой контекст до `tasks.py` по этой
|
задачи, конвейер ревью и любой другой чужой контекст до `tasks.py` по этой
|
||||||
переменной не дотянутся. Мост — **вызов скилла через пространство имён**, а не
|
переменной не дотянутся. Мост — **вызов скилла через пространство имён**, а не
|
||||||
путь:
|
путь:
|
||||||
@@ -684,8 +684,8 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
|||||||
какие в проекте оракулы — семантика гейта в `CLAUDE.md`. Отдельными слотами
|
какие в проекте оракулы — семантика гейта в `CLAUDE.md`. Отдельными слотами
|
||||||
остаётся то, чего из раскладки не вывести. **Проект дописывает в `CLAUDE.md`**:
|
остаётся то, чего из раскладки не вывести. **Проект дописывает в `CLAUDE.md`**:
|
||||||
|
|
||||||
1. **Что такое «сделана»** — чем задача выполняется (пайплайн проекта) и что
|
1. **Что такое «сделана»** — чем задача выполняется (конвейер проекта) и что
|
||||||
входит в его определение готовности. Скилл требует лишь **форму**: пайплайн
|
входит в его определение сделанного. Скилл требует лишь **форму**: конвейер
|
||||||
проекта пройден + критерии приёмки проверены поимённо.
|
проекта пройден + критерии приёмки проверены поимённо.
|
||||||
2. **Что считается необратимым** и потому спрашивается у человека всегда
|
2. **Что считается необратимым** и потому спрашивается у человека всегда
|
||||||
(деплой, выкладка наружу, удаление или перезапись данных).
|
(деплой, выкладка наружу, удаление или перезапись данных).
|
||||||
@@ -713,7 +713,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
|||||||
## Чего этот скилл не делает
|
## Чего этот скилл не делает
|
||||||
|
|
||||||
Не пишет код, не заводит спеки и предложения об изменении, не берёт задачу в
|
Не пишет код, не заводит спеки и предложения об изменении, не берёт задачу в
|
||||||
работу — этим занимается пайплайн проекта. **Не ведёт очередь:** что делать
|
работу — этим занимается конвейер проекта. **Не ведёт очередь:** что делать
|
||||||
следующим и что перестало быть важным — скилл `groom`, а этот даёт ему операции.
|
следующим и что перестало быть важным — скилл `groom`, а этот даёт ему операции.
|
||||||
Не решает за пользователя, что важно. Не
|
Не решает за пользователя, что важно. Не
|
||||||
переоформляет существующие задачи «заодно»: правится то, чего касается операция.
|
переоформляет существующие задачи «заодно»: правится то, чего касается операция.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
заходом и не мерджится целиком — это несколько задач под одной целью, дроби
|
заходом и не мерджится целиком — это несколько задач под одной целью, дроби
|
||||||
сразу ([split.md](split.md)). Промежуточного зонтика между целью и задачей
|
сразу ([split.md](split.md)). Промежуточного зонтика между целью и задачей
|
||||||
нет.
|
нет.
|
||||||
6. **Реализация** — дело пайплайна проекта, не этого скилла. Закрывается
|
6. **Реализация** — дело конвейера проекта, не этого скилла. Закрывается
|
||||||
`close <слаг> --implemented`: файл и строка удаляются, суть переезжает в
|
`close <слаг> --implemented`: файл и строка удаляются, суть переезжает в
|
||||||
`openspec/specs/` и документацию.
|
`openspec/specs/` и документацию.
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
|
|
||||||
2–5 проверяемых утверждений **списком** `- …`, **у каждого назван оракул**. Не
|
2–5 проверяемых утверждений **списком** `- …`, **у каждого назван оракул**. Не
|
||||||
«работает корректно», а «повторный прогон даёт тот же отпечаток — оракул:
|
«работает корректно», а «повторный прогон даёт тот же отпечаток — оракул:
|
||||||
команда сверки». Это не второе определение готовности, а проектная
|
команда сверки». Это не второе определение сделанного, а проектная
|
||||||
конкретизация вопроса «по чему видно, что закончено» из теста готовности ниже:
|
конкретизация вопроса «по чему видно, что закончено» из теста готовности ниже:
|
||||||
там сказано «признак завершённости», здесь — «признак плюс чем проверяется».
|
там сказано «признак завершённости», здесь — «признак плюс чем проверяется».
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# **Что судится — staged-файлы, а не рабочее дерево**, всюду, где проверка
|
# **Что судится — staged-файлы, а не рабочее дерево**, всюду, где проверка
|
||||||
# умеет смотреть поимённо: гейт обязан судить то, что уедет в историю, а не то,
|
# умеет смотреть поимённо: гейт обязан судить то, что уедет в историю, а не то,
|
||||||
# что случайно лежит на диске рядом. Два исключения названы у своих задач, и оба
|
# что случайно лежит на диске рядом. Три исключения названы у своих задач, и все
|
||||||
# — про то, что проверке нужен весь репозиторий по существу, а не для удобства.
|
# — про то, что проверке нужен весь репозиторий по существу, а не для удобства.
|
||||||
#
|
#
|
||||||
# Ставится `lefthook install` (см. README, «Гейт коммита»). Обойти разово —
|
# Ставится `lefthook install` (см. README, «Гейт коммита»). Обойти разово —
|
||||||
@@ -23,9 +23,12 @@ pre-commit:
|
|||||||
# copies.py сверяет копию с домом, а дом лежит в другом файле, которого в
|
# copies.py сверяет копию с домом, а дом лежит в другом файле, которого в
|
||||||
# индексе может не быть: список staged дал бы «копии дословны» там, где
|
# индексе может не быть: список staged дал бы «копии дословны» там, где
|
||||||
# правка дома их и разошлась. frontmatter.py смотрел бы поимённо, но весь
|
# правка дома их и разошлась. frontmatter.py смотрел бы поимённо, но весь
|
||||||
# обход стоит сотые доли секунды — платить за него нечем.
|
# обход стоит сотые доли секунды — платить за него нечем. Glob у него шире
|
||||||
|
# на `*.json`: тем же проходом сверяется `description` плагина в
|
||||||
|
# `plugin.json` с записью того же плагина в `marketplace.json`, а коммит,
|
||||||
|
# правящий только манифест, по глобу `*.md` проверку бы не разбудил.
|
||||||
- name: фронтматтеры
|
- name: фронтматтеры
|
||||||
glob: "*.md"
|
glob: "*.{md,json}"
|
||||||
run: python3 scripts/frontmatter.py
|
run: python3 scripts/frontmatter.py
|
||||||
|
|
||||||
- name: копии правил
|
- name: копии правил
|
||||||
|
|||||||
+54
-5
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Проверка фронтматтеров скиллов и charter'ов этого репозитория.
|
"""Проверка фронтматтеров скиллов и charter'ов этого репозитория и описаний плагинов.
|
||||||
|
|
||||||
Фронтматтер — единственная часть скилла, которую читает не человек, а загрузчик:
|
Фронтматтер — единственная часть скилла, которую читает не человек, а загрузчик:
|
||||||
по `name` он разрешает вызов, по `description` решает, звать ли скилл вообще.
|
по `name` он разрешает вызов, по `description` решает, звать ли скилл вообще.
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
разумную строку, а скилл либо не находится по имени, либо загружается с
|
разумную строку, а скилл либо не находится по имени, либо загружается с
|
||||||
обрезанным описанием и потому не срабатывает на своих же триггерах.
|
обрезанным описанием и потому не срабатывает на своих же триггерах.
|
||||||
|
|
||||||
Ловится три класса.
|
Ловится четыре класса.
|
||||||
|
|
||||||
**Двоеточие с пробелом в описании без кавычек.** В YAML `: ` внутри простого
|
**Двоеточие с пробелом в описании без кавычек.** В YAML `: ` внутри простого
|
||||||
скаляра начинает вложенное отображение — строка «конвейер ревью: гейт, сверка…»
|
скаляра начинает вложенное отображение — строка «конвейер ревью: гейт, сверка…»
|
||||||
@@ -26,8 +26,14 @@
|
|||||||
списку агентов, и держаться вниманием оно не может: цвет ставится один раз при
|
списку агентов, и держаться вниманием оно не может: цвет ставится один раз при
|
||||||
заведении charter'а, а модель потом меняется калибровкой.
|
заведении charter'а, а модель потом меняется калибровкой.
|
||||||
|
|
||||||
|
**Описание плагина, разошедшееся между манифестами.** У описания два дома:
|
||||||
|
`<плагин>/.claude-plugin/plugin.json` его показывает установленному плагину,
|
||||||
|
корневой `.claude-plugin/marketplace.json` — тому, кто выбирает, ставить ли.
|
||||||
|
Правят обычно один, и разойтись они успели уже трижды из четырёх. `copies.py`
|
||||||
|
этот класс не берёт: он смотрит markdown, а манифест — json.
|
||||||
|
|
||||||
Коды выхода — тот же словарь, что у tasks.py, docs.py, copies.py и diagrams.py:
|
Коды выхода — тот же словарь, что у tasks.py, docs.py, copies.py и diagrams.py:
|
||||||
0 все фронтматтеры в порядке
|
0 все фронтматтеры и описания в порядке
|
||||||
1 расхождение
|
1 расхождение
|
||||||
2 ошибка употребления: аргументы
|
2 ошибка употребления: аргументы
|
||||||
3 окружение: не тот каталог
|
3 окружение: не тот каталог
|
||||||
@@ -37,6 +43,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -129,6 +136,40 @@ def collect(root: Path) -> list[tuple[Sheet, str, set[str]]]:
|
|||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
def manifests(root: Path) -> list[tuple[str, list[str]]]:
|
||||||
|
"""Описание каждого плагина: `plugin.json` против `marketplace.json`."""
|
||||||
|
market = root / ".claude-plugin" / "marketplace.json"
|
||||||
|
where = market.relative_to(root).as_posix()
|
||||||
|
try:
|
||||||
|
listed = {
|
||||||
|
str(entry.get("name", "")): str(entry.get("description", ""))
|
||||||
|
for entry in json.loads(market.read_text(encoding="utf-8"))["plugins"]
|
||||||
|
}
|
||||||
|
except (OSError, ValueError, KeyError, TypeError) as e:
|
||||||
|
return [(where, [f"манифест маркетплейса не разбирается: {e}"])]
|
||||||
|
|
||||||
|
found: list[tuple[str, list[str]]] = []
|
||||||
|
for plugin in sorted(root.glob("av-*/")):
|
||||||
|
card = plugin / ".claude-plugin" / "plugin.json"
|
||||||
|
rel = card.relative_to(root).as_posix()
|
||||||
|
try:
|
||||||
|
own = json.loads(card.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, ValueError) as e:
|
||||||
|
found.append((rel, [f"манифест плагина не разбирается: {e}"]))
|
||||||
|
continue
|
||||||
|
name = str(own.get("name", plugin.name))
|
||||||
|
if name not in listed:
|
||||||
|
found.append((rel, [
|
||||||
|
f"плагина `{name}` нет в {where} — маркетплейс его не отдаёт"
|
||||||
|
]))
|
||||||
|
elif str(own.get("description", "")) != listed[name]:
|
||||||
|
found.append((rel, [
|
||||||
|
f"`description` разошлось с записью `{name}` в {where}:"
|
||||||
|
f" у описания один текст на два манифеста, и правят обычно один"
|
||||||
|
]))
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
ap = argparse.ArgumentParser(description="Проверка фронтматтеров.")
|
ap = argparse.ArgumentParser(description="Проверка фронтматтеров.")
|
||||||
ap.add_argument("--dir", default=".", help="корень репозитория")
|
ap.add_argument("--dir", default=".", help="корень репозитория")
|
||||||
@@ -150,17 +191,25 @@ def main() -> int:
|
|||||||
if sheet.parsed:
|
if sheet.parsed:
|
||||||
sheet.check(expected, required)
|
sheet.check(expected, required)
|
||||||
|
|
||||||
|
cards = manifests(root)
|
||||||
|
plugins = len(list(root.glob("av-*/")))
|
||||||
|
|
||||||
skills = sum(1 for _, _, required in sheets if required is SKILL_KEYS)
|
skills = sum(1 for _, _, required in sheets if required is SKILL_KEYS)
|
||||||
print(f"фронтматтеров {len(sheets)}: скиллов {skills},"
|
print(f"фронтматтеров {len(sheets)}: скиллов {skills},"
|
||||||
f" charter'ов {len(sheets) - skills}")
|
f" charter'ов {len(sheets) - skills}")
|
||||||
|
print(f"манифестов плагинов {plugins}: описание сверено с marketplace.json")
|
||||||
|
|
||||||
broken = [sheet for sheet, _, _ in sheets if sheet.problems]
|
broken = [sheet for sheet, _, _ in sheets if sheet.problems]
|
||||||
if broken:
|
if broken or cards:
|
||||||
print()
|
print()
|
||||||
for sheet in broken:
|
for sheet in broken:
|
||||||
for problem in sheet.problems:
|
for problem in sheet.problems:
|
||||||
print(f"ОШИБКА {sheet.where}\n {problem}")
|
print(f"ОШИБКА {sheet.where}\n {problem}")
|
||||||
print(f"\nИтог: с ошибками {len(broken)} из {len(sheets)}.")
|
for rel, problems in cards:
|
||||||
|
for problem in problems:
|
||||||
|
print(f"ОШИБКА {rel}\n {problem}")
|
||||||
|
print(f"\nИтог: с ошибками {len(broken) + len(cards)}"
|
||||||
|
f" из {len(sheets) + plugins}.")
|
||||||
return DRIFT
|
return DRIFT
|
||||||
|
|
||||||
print("все в порядке")
|
print("все в порядке")
|
||||||
|
|||||||
Reference in New Issue
Block a user