From dd69251d0402fc9c70a76e64122a5ec2ac6863a3 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Mon, 3 Aug 2026 20:32:17 +0300 Subject: [PATCH] =?UTF-8?q?mermaid=20=D1=82=D0=B0=D0=BC,=20=D0=B3=D0=B4?= =?UTF-8?q?=D0=B5=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0?= =?UTF-8?q?=20=E2=80=94=20=D0=B3=D1=80=D0=B0=D1=84=20=D0=B8=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Критерий: диаграмма заводится, если структура граф или автомат, а проза вынуждена его пересказывать. Где структура таблица соответствий — чек-лист синка, профили ревью, коды выхода — не заводится: дублировала бы таблицу и разошлась с ней. tasks: жизненный цикл записи по индексам — состояния это где числится строка, файл items/ не двигается ни на одном переходе. session: четыре шага сессии; текст говорил «это зависимость, а не список», но зависимости не показывал — теперь на рёбрах написано, что ломается. sprint.md: исходы задачи в спринте плюс два ребра, где порядок нарушается молча — урожай до sprint close и блокер в обход исходов. task-pipeline: одиннадцать шагов с развилкой «тривиальная» и досрочным исходом «крупнее задачи». promote.md: храповик находка → конвенция → правило → удаление, с обратным ребром; обязательность третьего шага теперь видна как ребро. calibration.md: счётчик retune до drop — таблица вердиктов его выразить не может, автомат может. README: граф вызовов между плагинами; односторонность зависимости pipeline → pm видна сразу. Все девять блоков прогнаны через mermaid-cli. README-схема и автомат калибровки переверстаны после просмотра: subgraph'ы ломали раскладку, self-loop наезжал подписями. Co-Authored-By: Claude Opus 5 (1M context) --- DECISIONS.md | 18 +++++++++-- README.md | 30 +++++++++++++++++++ .../review-pipeline/references/calibration.md | 17 +++++++++++ .../review-pipeline/references/promote.md | 21 +++++++++++++ av-dev-pipeline/skills/task-pipeline/SKILL.md | 30 +++++++++++++++++++ av-dev-pm/skills/session/SKILL.md | 19 ++++++++++++ av-dev-pm/skills/session/references/sprint.md | 30 +++++++++++++++++++ av-dev-pm/skills/tasks/SKILL.md | 28 +++++++++++++++++ 8 files changed, 190 insertions(+), 3 deletions(-) diff --git a/DECISIONS.md b/DECISIONS.md index 9f7f38b..d8b7d6f 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -1033,9 +1033,21 @@ HTML-комментарии, невидимые в отрендеренном ma ровно эту ошибку. Исключение одно и оно же сток: триаж. **BBB. Диаграммы в скиллах — `mermaid`.** Граф, описанный прозой, читается как -инструкция и теряет форму; диаграмма показывает её целиком. Четыре штуки: общий -граф прогона, граф профиля `design`, пример графа задач батча, веер финальной -сверки. +инструкция и теряет форму; диаграмма показывает её целиком. В конвейере четыре: +общий граф прогона, граф профиля `design`, пример графа задач батча, веер +финальной сверки. + +**Критерий, где диаграмма уместна: структура — граф или автомат, и проза +вынуждена его пересказывать.** По этому критерию диаграммы заведены ещё в шести +местах: жизненный цикл записи по индексам (`tasks`), четыре шага сессии с +причинами на рёбрах (`session`), исходы задачи в спринте (`sprint.md`), одиннадцать +шагов пайплайна с развилкой «тривиальная» (`task-pipeline`), храповик промоута с +обратным ребром (`promote.md`), счётчик `retune` до `drop` (`calibration.md`) и +граф вызовов между плагинами (`README.md`). Где структура — таблица соответствий +(чек-лист синка в `docs`, профили ревью, коды выхода), диаграмма не заводится: +она бы дублировала таблицу и разошлась с ней. Все диаграммы прогоняются через +`mermaid-cli` перед коммитом — синтаксическая ошибка в блоке не видна при чтении +и молча ломает рендер. ### Что из этого следует diff --git a/README.md b/README.md index d309c30..1d94cb4 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,36 @@ Соглашение об именах: имя **плагина** длинное с префиксом `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
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:* — внешний плагин:
explore, propose, apply, archive"] + git["av-dev-git: commit"] + + tp --> opsx + tp --> git + tp --> docs + tp --> tasks +``` + +Зависимость **односторонняя: `av-dev-pipeline` знает про `av-dev-pm`, обратно — +нет.** Управление продуктом работает в проекте без конвейера; конвейер без +канона деградирует поразрядно и говорит об этом строкой. + ## Канон документов проекта Все проекты приводятся к одной раскладке — так проще ориентироваться, когда diff --git a/av-dev-pipeline/skills/review-pipeline/references/calibration.md b/av-dev-pipeline/skills/review-pipeline/references/calibration.md index d6425f0..63b258c 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/calibration.md +++ b/av-dev-pipeline/skills/review-pipeline/references/calibration.md @@ -23,6 +23,23 @@ | `retune` уже был дважды подряд | `drop` | удаляем проход | | находит, но ложных больше трети от всех находок | `retune` | триаж съедает больше, чем экономит проход | +Вердикты образуют храповик со счётчиком — его-то таблица и не показывает: + +```mermaid +stateDiagram-v2 + state "проход в профиле" as live + state "retune №1 — правка charter'а" as r1 + state "retune №2 — последняя попытка" as r2 + state "проход удалён" as dead + + [*] --> live: заведён и откалиброван ДО включения + live --> r1: 1/3, 0/3 или ложных больше трети + r1 --> live: замер keep — счётчик сброшен + r1 --> r2: снова не ловит + r2 --> live: замер keep — счётчик сброшен + r2 --> dead: снова не ловит — это театр +``` + **`retune` не более двух раз подряд.** Проход, не находящий дефект своего класса в 2 из 3 прогонов после двух правок промпта, — это театр. Удалять, а не бесконечно править формулировки: каждая итерация правки промпта стоит дороже, diff --git a/av-dev-pipeline/skills/review-pipeline/references/promote.md b/av-dev-pipeline/skills/review-pipeline/references/promote.md index 89e9287..9b84354 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/promote.md +++ b/av-dev-pipeline/skills/review-pipeline/references/promote.md @@ -11,6 +11,27 @@ - **правила линтера** — то же с детерминированным оракулом и нулевой ценой внимания. +```mermaid +flowchart TD + f["находка ревью"] + cond{"принята и не специфична
для одного места?"} + no["промоуту не подлежит:
место одно — комментарий в коде;
вкусовщина — вон на триаже;
нужен рантайм — в журнал ревью"] + conv["конвенция:
проверяемое свойство + какой проход нашёл"] + rule["правило линтера, запретитель,
тест-сканер или анализатор"] + clean["шаг 3: формулировка удалена из конвенций,
строка — в conventions/README.md"] + + f --> cond + cond -->|нет| no + cond -->|да| conv + conv --> rule + rule --> clean + rule -->|"ложных чаще, чем ловит (~треть)"| conv +``` + +Ребро назад — обратное движение (внизу): правило, дающее ложные срабатывания +чаще, чем ловит, снимается в прозу. Ребро `rule → clean` **обязательное**: без +него первые два шага не окупаются, а именно его и пропускают. + ## Шаг 1. Находка → конвенция Условия: находка **принята** при ревью (не отвергнута, не понижена в гипотезу) и diff --git a/av-dev-pipeline/skills/task-pipeline/SKILL.md b/av-dev-pipeline/skills/task-pipeline/SKILL.md index 3e2d14b..9dd805a 100644 --- a/av-dev-pipeline/skills/task-pipeline/SKILL.md +++ b/av-dev-pipeline/skills/task-pipeline/SKILL.md @@ -148,6 +148,36 @@ description: Автономно проводит одну задачу чере ## Шаги +Одиннадцать шагов с одной развилкой и одним досрочным исходом: + +```mermaid +flowchart TD + s1["1. Прочитать задачу
критерии приёмки выписать сразу"] + triv{"тривиальная?"} + big["исход «оказалась крупнее задачи»
объявляется ДО заведения change"] + s2["2. opsx:explore — груминг идеи"] + s3["3. opsx:propose — change, дельта-спеки, tasks.md"] + s4["4. ревью предложения, профиль design"] + s5["5. отработать замечания + validate --strict"] + s6["6. opsx:apply — код, гейт, поведенческая верификация"] + s7["7. ревью кода, профиль по факту изменения"] + s8["8. opsx:archive"] + s9["9. синк документации — av-dev-pm:docs"] + s10["10. коммит работы — av-dev-git:commit"] + s11["11. закрыть задачу — av-dev-pm:tasks,
вторым коммитом учёта"] + + s1 --> triv + s1 -.-> big + triv -->|"нет: идея или мутная постановка"| s2 + s2 --> s3 + triv -->|"да: шаги 2 и 4 пропускаются"| s3 + s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10 --> s11 +``` + +Два чекпоинта ревью — шаги 4 и 7 — единственные места, где зовётся конвейер; +порядок «сперва коммит работы, потом коммит учёта» на схеме тоже ребро, и оно +обязательное (шаг 11). + ### 1. Прочитать задачу Задача задана извне (slug, файл, ссылка, описание) — прочитай её и связанные diff --git a/av-dev-pm/skills/session/SKILL.md b/av-dev-pm/skills/session/SKILL.md index f1976f3..5da0426 100644 --- a/av-dev-pm/skills/session/SKILL.md +++ b/av-dev-pm/skills/session/SKILL.md @@ -121,6 +121,25 @@ description: Ритуал между спринтами и ведение сам 4. **Выбор цели и набор спринта.** Цель называет человек, набор собирает агент и показывает **до старта работ**. +Рёбра подписаны тем, что ломается при их нарушении: + +```mermaid +flowchart TD + check["tasks.py check (+ --fix)
результат — строкой в доклад"] + s1["1. Разбор вопросов
пачкой, не больше трёх за раз"] + s2["2. Разбор прошедшего спринта
про процесс → docs/review.md"] + s3["3. Переоценка задач порциями"] + s4["4. Цель называет человек,
набор собирает агент"] + sprint["спринт: набор заморожен"] + + check --> s1 + s1 --> s2 + s2 --> s3 + s1 -->|"неотвеченный вопрос → переоценка вслепую"| s3 + s3 -->|"без переоценки набор берётся из протухшего"| s4 + s4 --> sprint +``` + Процедура каждого шага, размер и отбор порции, храповик на залежавшихся, формат интерактива и доклад — [references/cadence.md](references/cadence.md). diff --git a/av-dev-pm/skills/session/references/sprint.md b/av-dev-pm/skills/session/references/sprint.md index bc88790..a3a49d4 100644 --- a/av-dev-pm/skills/session/references/sprint.md +++ b/av-dev-pm/skills/session/references/sprint.md @@ -29,6 +29,36 @@ «все сделаны»: иначе одна застрявшая задача держит спринт бесконечно. Затем `sprint close`. +```mermaid +flowchart TD + take["sprint take — задача в наборе"] + done["сделана
close --implemented"] + out["вышла
sprint drop --reason"] + epic["переросла в эпик
распознаётся до заведения change"] + cancel["отменена решением по ходу
close --reason"] + all{"по каждой задаче набора
наступил исход?"} + harvest["урожай заводится интейком tasks"] + close["sprint close"] + dissolve["sprint close --dissolve --reason
недоделанное — в беклог"] + + take --> done + take --> out + take --> epic + take --> cancel + done --> all + out --> all + epic --> all + cancel --> all + all -->|да| harvest + harvest -->|"тег sprint: ставится, пока SPRINT.md не очищен"| close + take -->|"продолжать нечем ни одной задачей — блокер"| dissolve + done -->|"приёмка не сошлась: reopen --reason"| take +``` + +Два ребра на схеме — те, где порядок обязателен и нарушается молча: **урожай до +`sprint close`** (после команды автотег уже не поставится) и **блокер в обход +исходов** (спринт распускается, а не ждёт). + **Урожай заводится при закрытии спринта, а не при закрытии задачи.** Это обязанность закрывающего: пройти по спискам находок от исполнителей и завести недостающее интейком скилла `tasks` — с дедупликацией и картой человеку. Заводимое diff --git a/av-dev-pm/skills/tasks/SKILL.md b/av-dev-pm/skills/tasks/SKILL.md index c1e823a..1b4cfae 100644 --- a/av-dev-pm/skills/tasks/SKILL.md +++ b/av-dev-pm/skills/tasks/SKILL.md @@ -77,6 +77,34 @@ docs/tasks/ даром: `SPRINT.md` лежит под git, `git log -p docs/tasks/SPRINT.md` отдаёт историю всех наборов без отдельного журнала. +Куда запись может переехать и какой командой — весь набор переходов: + +```mermaid +stateDiagram-v2 + state "BACKLOG.md — что берут" as B + state "PLAN.md — подо что берут" as P + state "SPRINT.md — набор спринта" as S + state "REJECTED.md — ушла без реализации" as R + state "записи нет — реализована" as D + + [*] --> B: add + [*] --> P: add --type goal + B --> P: edit --type goal --section + P --> B: edit --type task --section + B --> S: sprint take + S --> B: sprint drop --reason + S --> D: close --implemented + B --> R: close --reason + S --> R: close --reason + D --> B: reopen --reason + R --> B: reopen --reason +``` + +Состояния здесь — **где числится строка**, а не где лежит файл: файл +`items/.md` не двигается ни на одном переходе. Стрелок «руками» на схеме +нет намеренно — каждый переход это команда, и другого способа его совершить не +существует. + ## Цели **Цель — такой же файл в `items/`, тип `[goal]`**, перечисленный в `PLAN.md`: