Диаграмма и проза вокруг неё описывают один факт — это второй дом, и разойтись они могут молча: то самое, против чего написан copies.py. Механической сверки здесь нет, дословного соответствия между текстом и графом не существует, поэтому работает объявление. В review-pipeline старший граф — он и есть алгоритм планировщика, проза объясняет рёбра; в остальных местах старшая проза, диаграмма там сводка; в calibration.md старшая таблица вердиктов, схема добавляет к ней только счётчик. Объявление стоит у каждой диаграммы строкой в месте, а не общим правилом в README: скилл читают целиком, README — нет. В task-batch добавлена оговорка про соседний скилл — два вызова с разным старшинством рядом это место, где легко ошибиться. scripts/diagrams.py вынимает все mermaid-блоки и рендерит каждый через mmdc или npx @mermaid-js/mermaid-cli. Коды выхода — общий словарь; нет рендерера — код 3, а не молчаливый успех. Chromium с --no-sandbox: без флага падает на «No usable sandbox», причина в докстроке. Проверены обе ветки: 11 диаграмм в 9 файлах зелено, сломанный блок даёт точное место с текстом ошибки парсера и код 1. README: раздел «Проверка диаграмм» рядом с проверкой копий — что ловит, чего не ловит и почему не в гейте. DECISIONS 63 и 64. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
221 lines
13 KiB
Markdown
221 lines
13 KiB
Markdown
# av-dev-skills
|
||
|
||
Личный маркетплейс плагинов для разработки. Процесс имени не имеет — он и есть
|
||
`av-dev`.
|
||
|
||
Что решено и почему — [DECISIONS.md](DECISIONS.md). Что осталось сделать —
|
||
[TODO.md](TODO.md) и [REMAINING.md](REMAINING.md). Как процесс дошёл до текущей
|
||
формы — [HISTORY.md](HISTORY.md).
|
||
|
||
## Плагины
|
||
|
||
- **av-dev-pm** — управление продуктом. Владеет всем `docs/`.
|
||
- `init` — новый проект: интервью по свободному описанию замысла → первичная
|
||
документация;
|
||
- `canon` — привести проект к канону документов: `check` / `adopt` /
|
||
`upgrade`, плюс скрипт `docs.py`;
|
||
- `docs` — содержимое канона по ходу разработки: ADR из архивного
|
||
`design.md`, промоут конвенций, запись в разведку и журнал ревью, чистка
|
||
архитектуры;
|
||
- `tasks` — задачи и цели каталогом markdown-файлов;
|
||
- `session` — ритуал между спринтами и ведение спринта.
|
||
- **av-dev-pipeline** — исполнение. **Требует OpenSpec.**
|
||
- `task-pipeline` — задача через полный цикл SDD, от постановки до коммита;
|
||
- `task-batch` — несколько задач разом, каждая в своём worktree;
|
||
- `review-pipeline` — конвейер ревью: гейт, сверка со спеками, враждебные
|
||
постановки, эксплуатационный постмортем, независимая реализация,
|
||
архитектура, обязательный триаж. Девять агентов-проходов.
|
||
- **av-dev-git** — `commit`: сообщения в личном стиле.
|
||
- **av-dev-backlog** — **устарел**, заменён `av-dev-pm`. Живёт до перевода
|
||
последнего проекта.
|
||
|
||
Соглашение об именах: имя **плагина** длинное с префиксом `av-dev-`, имена
|
||
**скилов** внутри — короткие. Вызов выходит вида `/av-dev-<плагин>:<скилл>`.
|
||
|
||
Кто кого зовёт (стрелка — вызов через пространство имён, не импорт):
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph pipe["av-dev-pipeline — исполнение, требует OpenSpec"]
|
||
direction LR
|
||
batch["task-batch"] --> tp["task-pipeline"]
|
||
tp --> rp["review-pipeline<br/>9 агентов-проходов"]
|
||
batch --> rp
|
||
end
|
||
subgraph pm["av-dev-pm — управление продуктом, владеет docs/"]
|
||
direction LR
|
||
init["init"] --> tasks["tasks"]
|
||
canon["canon"] --> tasks
|
||
session["session"] --> tasks
|
||
docs["docs"]
|
||
end
|
||
opsx["opsx:* — внешний плагин:<br/>explore, propose, apply, archive"]
|
||
git["av-dev-git: commit"]
|
||
|
||
tp --> opsx
|
||
tp --> git
|
||
tp --> docs
|
||
tp --> tasks
|
||
```
|
||
|
||
Зависимость **односторонняя: `av-dev-pipeline` знает про `av-dev-pm`, обратно —
|
||
нет.** Управление продуктом работает в проекте без конвейера; конвейер без
|
||
канона деградирует поразрядно и говорит об этом строкой.
|
||
|
||
## Канон документов проекта
|
||
|
||
Все проекты приводятся к одной раскладке — так проще ориентироваться, когда
|
||
проектов много, и рядом OpenSpec тоже держит строгую структуру. Определение —
|
||
[av-dev-pm/skills/canon/references/canon.md](av-dev-pm/skills/canon/references/canon.md).
|
||
|
||
```
|
||
CLAUDE.md инварианты с severity, команды, семантика гейта
|
||
docs/
|
||
.pm.json версия канона и пути для проверок
|
||
passport.md зачем и для кого; чем НЕ является
|
||
architecture.md как сложено — обзор; окружение и эксплуатация
|
||
database.md схема хранилища; настройки с числовым значением
|
||
security.md периметр; недоверенный вход; что вне модели
|
||
conventions/ как пишем код + что уже механизировано
|
||
research/ что показала реальность; числа с провенансом
|
||
adr/ почему — промоут поверх архивных design.md
|
||
review.md настройка конвейера + журнал дефектов
|
||
tasks/ цели, беклог, спринт, отклонённое
|
||
openspec/
|
||
specs/<capability>/spec.md что система делает — нормативно
|
||
changes/archive/ архив изменений с design.md
|
||
```
|
||
|
||
**Отдельного файла-брифа для ревью нет.** Проходы читают эти документы напрямую;
|
||
карта «что нужно проходу → где лежит» —
|
||
[project-facts.md](av-dev-pipeline/skills/review-pipeline/references/project-facts.md).
|
||
|
||
Прийти в старый проект и перевести его на канон — `/av-dev-pm:canon`. Канон
|
||
версионируется, и проекты повышаются по [журналу
|
||
версий](av-dev-pm/skills/canon/references/changelog.md).
|
||
|
||
## Подключение
|
||
|
||
Плагин подключается **на уровне проекта**, чтобы был активен у всех, кто
|
||
открывает репозиторий:
|
||
|
||
```
|
||
/plugin marketplace add https://git.vakhrushev.me/av/dev-skills.git --scope project
|
||
/plugin install av-dev-pm@av-dev-skills --scope project
|
||
/plugin install av-dev-pipeline@av-dev-skills --scope project
|
||
/plugin install av-dev-git@av-dev-skills --scope project
|
||
```
|
||
|
||
…или те же команды из терминала через `claude plugin …`. Обе формы дописывают в
|
||
`.claude/settings.json` проекта то, что можно внести и руками:
|
||
|
||
```json
|
||
{
|
||
"extraKnownMarketplaces": {
|
||
"av-dev-skills": {
|
||
"source": { "source": "git", "url": "https://git.vakhrushev.me/av/dev-skills.git" }
|
||
}
|
||
},
|
||
"enabledPlugins": {
|
||
"av-dev-pm@av-dev-skills": true,
|
||
"av-dev-pipeline@av-dev-skills": true,
|
||
"av-dev-git@av-dev-skills": true
|
||
}
|
||
}
|
||
```
|
||
|
||
**Маркетплейс — git-клон удалённого репозитория, и он обновляется явно:**
|
||
`claude plugin marketplace update av-dev-skills`. Локальные коммиты, не
|
||
отправленные на origin, до него не доедут — это уже однажды выглядело как
|
||
«плагин не работает».
|
||
|
||
**При установке в проект, где лежали проектные копии** скиллов и агентов
|
||
(`.claude/skills/` — голые `task-pipeline`, `review-pipeline`, `task-batch`
|
||
и с префиксом проекта `<проект>-task-pipeline`,
|
||
`.claude/agents/<проект>-review-*.md`) — снеси их. Две копии одного скилла
|
||
расходятся, и побеждает та, что короче названа.
|
||
|
||
## Структура репозитория
|
||
|
||
```
|
||
.claude-plugin/marketplace.json манифест маркетплейса
|
||
<plugin>/.claude-plugin/plugin.json манифест плагина
|
||
<plugin>/skills/<skill>/SKILL.md скилы (авто-обнаружение)
|
||
<plugin>/skills/<skill>/references/ что читается по ссылке из скилла
|
||
<plugin>/skills/<skill>/scripts/ tasks.py, docs.py
|
||
<plugin>/agents/ charter'ы сабагентов
|
||
scripts/ проверки самого репозитория: копии, диаграммы
|
||
pyproject.toml линтеры скриптов, только для этого репозитория
|
||
```
|
||
|
||
## Проверка скриптов
|
||
|
||
`tasks.py` и `docs.py` запускаются **где угодно голым `python3` 3.12 без
|
||
установки чего-либо** — они лежат рядом со скиллами и работают в любом проекте.
|
||
`pyproject.toml` в корне не меняет этого: он живёт только здесь и держит
|
||
линтеры, а не зависимости скриптов.
|
||
|
||
```
|
||
uv sync # ставит ruff и pyrefly в .venv, версии прибиты точно
|
||
uv run ruff check . # правила; --fix для безопасных починок
|
||
uv run pyrefly check # типы
|
||
```
|
||
|
||
Ноль внешних зависимостей охраняется двумя способами: `banned-api` у ruff ловит
|
||
частые соблазны по имени, а pyrefly видит окружение, где нет ничего кроме
|
||
линтеров, и любой сторонний импорт у него не разрешается. Список запретов —
|
||
не перечень мира, настоящий страж второй.
|
||
|
||
`av-dev-backlog` из проверки исключён намеренно: плагин помечен устаревшим и
|
||
живёт до перевода последнего проекта, после чего удаляется целиком. Правки в
|
||
замороженный код — риск без выгоды.
|
||
|
||
## Проверка копий правил
|
||
|
||
«Один факт — один дом» держалось вниманием и трижды не удержалось. Копии всё же
|
||
нужны: скелеты канона уезжают в репозиторий проекта и обязаны там что-то
|
||
говорить. Значит копия допустима, но **дословная и помеченная**:
|
||
|
||
```
|
||
uv run python scripts/copies.py # 0 сошлось, 1 расхождение, 2 разметка, 3 не тот каталог
|
||
```
|
||
|
||
Разметка — HTML-комментарии, невидимые в отрендеренном markdown:
|
||
|
||
```
|
||
<!-- дом: <id> --> …текст… <!-- /дом: <id> -->
|
||
<!-- копия: <id> из <путь к дому> --> …тот же текст… <!-- /копия: <id> -->
|
||
```
|
||
|
||
Идентификатор — буквы, цифры и дефис, и он повторяется в закрывающем маркере.
|
||
Строгость нужна ровно затем, чтобы этот абзац сам не объявил дом: `<id>` под
|
||
шаблон не подходит.
|
||
|
||
Сверяется текст между маркерами; ограда блока кода и пустые строки по краям в
|
||
сверку не входят. Маркер, уехавший в проект вместе со скелетом, там полезен: он
|
||
говорит, что у текста есть дом и правится он там.
|
||
|
||
Скрипт ловит четыре вещи: копия разошлась с домом (с диффом), копия указывает не
|
||
на тот файл, дом остался без копий, разметка сломана. Чего он **не** ловит —
|
||
копию, которую забыли пометить: помечать — по-прежнему решение человека.
|
||
|
||
## Проверка диаграмм
|
||
|
||
Диаграммы `mermaid` живут исходником в markdown — картинок в репозитории нет.
|
||
Синтаксическая ошибка в блоке **не видна при чтении**: текст выглядит
|
||
правдоподобно, диff показывает разумную строку, а рендер падает.
|
||
|
||
```
|
||
uv run python scripts/diagrams.py # 0 рендерятся, 1 нет, 3 нет mermaid-cli
|
||
```
|
||
|
||
Рендерит `mmdc` с PATH или `npx --yes @mermaid-js/mermaid-cli`; ни того ни
|
||
другого нет — код 3, а не молчаливый успех. Прогон занимает секунды на блок,
|
||
поэтому он не в гейте, а в руках того, кто правит диаграмму.
|
||
|
||
Чего проверка **не** ловит — расхождение диаграммы с прозой вокруг неё. Дословного
|
||
соответствия между текстом и графом нет, сличать нечего, и держится это
|
||
правилом старшинства, записанным рядом с каждой диаграммой: **в конвейере ревью
|
||
старший граф** (он и есть алгоритм планировщика, проза его объясняет), **в
|
||
остальных местах старшая проза** (диаграмма там сводка).
|