From 00ddfb0dde62ac50708695c46f02c61003c2b0fe Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 9 Aug 2026 14:06:26 +0300 Subject: [PATCH] =?UTF-8?q?av-dev-pm=20=D1=80=D0=B0=D1=81=D0=BA=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D1=82=20=D0=BD=D0=B0=20av-dev-docs=20=D0=B8=20av-d?= =?UTF-8?q?ev-tasks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Плагин владел двумя разными вещами сразу — документацией проекта и учётом работ, — и это мешало обеим. Канон нельзя было поставить без задач, задачи без канона, а язык проектных текстов лежал внутри скилла canon и потому принадлежал половине. Теперь плагина два, каждый ставится сам по себе. av-dev-docs: скиллы canon, docs, init; агенты doc-consistency, doc-code-drift, doc-wording; скрипт docs.py. av-dev-tasks: скиллы tasks, session; агенты task-form, task-wording; скрипт tasks.py. Между собой они зовутся через пространство имён, а не по пути в чужое дерево. Все относительные ссылки, пересекшие границу плагина, сняты: tasks больше не указывает в canon, canon не указывает в tasks. Вместо ссылки — имя скилла и оговорка, что вызов может не разрешиться, и это исход, а не поломка. То, что нужно обоим дословно, стало вторым общим домом. Словарь «Сопровождение и эксплуатация» назван в трёх местах трёх плагинов — секция роадмапа, раздел «Эксплуатация» в architecture.md, тема ревью operations — и ни один из трёх им не владеет; он уехал в shared/operations.md, а canon.md и скилл задач везут копии. Три перечня «чем держат проект» уже разъезжались на «метриках и логах» против «мониторинга», так что ссылка тут не годится: плагин, поставленный в одиночку, получил бы указатель в никуда. Тем же способом язык: у av-dev-tasks появилась своя копия language.md. Копий стало 18 при 8 домах. Переименования разведены по смыслу, а не заменой строки: где речь о каноне — av-dev-docs, где об учёте задач — av-dev-tasks. В пайплайне таких мест одиннадцать, и оба адресата там встречаются вперемешку. Журналы (DECISIONS, TODO, HISTORY) намеренно не тронуты: они описывают состояние на момент записи. По той же причине оставлена наблюдённая строка в комментарии docs.py — она цитирует конфиг живого проекта, а не называет плагин. Не входит в этот заход и названо отдельно: слияние canon и docs в один скилл, разделение docs/.pm.json на два конфига и переезд openspec в пайплайн. Гейт зелёный: копии, фронтматтеры, диаграммы, json. Оба скрипта прогнаны после переезда — docs.py version и tasks.py check на фикстуре. Co-Authored-By: Claude Opus 5 (1M context) --- .claude-plugin/marketplace.json | 13 +- README.md | 43 ++-- av-dev-docs/.claude-plugin/plugin.json | 8 + .../agents/doc-code-drift.md | 0 .../agents/doc-consistency.md | 4 +- .../agents/doc-wording.md | 0 .../skills/canon/SKILL.md | 5 +- .../skills/canon/references/canon.md | 17 +- .../skills/canon/references/changelog.md | 0 .../skills/canon/references/language.md | 0 .../skills/canon/references/skeletons.md | 2 +- .../skills/canon/scripts/docs.py | 0 .../skills/docs/SKILL.md | 0 .../skills/init/SKILL.md | 2 +- av-dev-pipeline/.claude-plugin/plugin.json | 2 +- .../skills/review-pipeline/SKILL.md | 12 +- .../references/project-facts.md | 6 +- .../references/review-journal.md | 4 +- .../references/review-levels.md | 2 +- av-dev-pipeline/skills/task-batch/SKILL.md | 8 +- av-dev-pipeline/skills/task-pipeline/SKILL.md | 32 +-- av-dev-pm/.claude-plugin/plugin.json | 8 - av-dev-tasks/.claude-plugin/plugin.json | 8 + .../agents/task-form.md | 0 .../agents/task-wording.md | 0 .../skills/session/SKILL.md | 7 +- .../skills/session/references/cadence.md | 0 .../skills/session/references/sprint.md | 2 +- .../skills/tasks/SKILL.md | 37 +-- .../skills/tasks/references/adopt.md | 2 +- .../skills/tasks/references/from-review.md | 0 .../skills/tasks/references/language.md | 211 ++++++++++++++++++ .../skills/tasks/references/operations.md | 34 +++ .../skills/tasks/references/split.md | 0 .../skills/tasks/references/task-chore.md | 0 .../skills/tasks/references/task-feature.md | 0 .../skills/tasks/references/task-fix.md | 0 .../skills/tasks/references/task-format.md | 0 .../skills/tasks/references/task-goal.md | 4 +- .../skills/tasks/references/task-research.md | 0 .../skills/tasks/scripts/tasks.py | 6 +- shared/operations.md | 35 +++ 42 files changed, 417 insertions(+), 97 deletions(-) create mode 100644 av-dev-docs/.claude-plugin/plugin.json rename {av-dev-pm => av-dev-docs}/agents/doc-code-drift.md (100%) rename {av-dev-pm => av-dev-docs}/agents/doc-consistency.md (98%) rename {av-dev-pm => av-dev-docs}/agents/doc-wording.md (100%) rename {av-dev-pm => av-dev-docs}/skills/canon/SKILL.md (98%) rename {av-dev-pm => av-dev-docs}/skills/canon/references/canon.md (98%) rename {av-dev-pm => av-dev-docs}/skills/canon/references/changelog.md (100%) rename {av-dev-pm => av-dev-docs}/skills/canon/references/language.md (100%) rename {av-dev-pm => av-dev-docs}/skills/canon/references/skeletons.md (99%) rename {av-dev-pm => av-dev-docs}/skills/canon/scripts/docs.py (100%) rename {av-dev-pm => av-dev-docs}/skills/docs/SKILL.md (100%) rename {av-dev-pm => av-dev-docs}/skills/init/SKILL.md (99%) delete mode 100644 av-dev-pm/.claude-plugin/plugin.json create mode 100644 av-dev-tasks/.claude-plugin/plugin.json rename {av-dev-pm => av-dev-tasks}/agents/task-form.md (100%) rename {av-dev-pm => av-dev-tasks}/agents/task-wording.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/session/SKILL.md (97%) rename {av-dev-pm => av-dev-tasks}/skills/session/references/cadence.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/session/references/sprint.md (99%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/SKILL.md (96%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/adopt.md (98%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/from-review.md (100%) create mode 100644 av-dev-tasks/skills/tasks/references/language.md create mode 100644 av-dev-tasks/skills/tasks/references/operations.md rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/split.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-chore.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-feature.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-fix.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-format.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-goal.md (96%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/references/task-research.md (100%) rename {av-dev-pm => av-dev-tasks}/skills/tasks/scripts/tasks.py (99%) create mode 100644 shared/operations.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index b2473d1..21296f5 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,14 +6,19 @@ }, "plugins": [ { - "name": "av-dev-pm", - "source": "./av-dev-pm", - "description": "Управление продуктом: канон документов проекта, задачи и цели вместо приоритетов, спринт под одну цель с заморозкой набора, старт проекта интервью по брифу и приведение существующего к канону. Ничего не выполняет сам и никакого пайплайна не требует: задача выполняется чем угодно, а канон описывает документы, из которых конвейер ревью берёт проектную конкретику." + "name": "av-dev-docs", + "source": "./av-dev-docs", + "description": "Документация проекта: канон раскладки docs/ и CLAUDE.md, роли документов, правило единственного дома. check / adopt / upgrade со скриптом docs.py, старт проекта интервью по брифу, ведение содержимого по ходу разработки. Ничего не выполняет сам и никакого пайплайна не требует." + }, + { + "name": "av-dev-tasks", + "source": "./av-dev-tasks", + "description": "Задачи и цели каталогом markdown-файлов, у каждой записи тип, и тип задаёт её схему. Спринт под одну цель, ритуал между спринтами, проверка согласованности скриптом tasks.py. Задача выполняется чем угодно: пайплайна плагин не требует и сам его не зовёт." }, { "name": "av-dev-pipeline", "source": "./av-dev-pipeline", - "description": "Проведение задачи через цикл SDD и конвейер ревью с обязательным триажем, плюс прогон нескольких задач разом. Требует OpenSpec. Задача принимается и обычным текстом; плагин av-dev-pm опционален — он даёт документы канона для проходов ревью и учёт задач, без него прогон деградирует поразрядно и говорит об этом." + "description": "Проведение задачи через цикл SDD и конвейер ревью с обязательным триажем, плюс прогон нескольких задач разом. Требует OpenSpec. Задача принимается и обычным текстом; плагины av-dev-docs и av-dev-tasks опциональны — первый даёт документы канона для проходов ревью, второй учёт задач, без них прогон деградирует поразрядно и говорит об этом." }, { "name": "av-dev-git", diff --git a/README.md b/README.md index 02f0354..6f9c962 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## Плагины -- **av-dev-pm** — управление продуктом. Владеет всем `docs/`. +- **av-dev-docs** — документация проекта. Владеет `docs/` и `CLAUDE.md`. - `init` — новый проект: интервью по свободному описанию замысла → первичная документация; - `canon` — привести проект к канону документов: `check` / `adopt` / @@ -20,7 +20,8 @@ `doc-code-drift` (документы против кода) и `doc-wording` (язык документов); - `docs` — содержимое канона по ходу разработки: ADR из архивного `design.md`, промоут конвенций, запись в разведку и журнал ревью, чистка - архитектуры; + архитектуры. +- **av-dev-tasks** — учёт работ. Владеет каталогом задач. - `tasks` — задачи и цели каталогом markdown-файлов, у каждой записи тип (`goal`, `feature`, `fix`, `chore`, `research`), и тип задаёт её схему; вычитывают их два отдельных прохода: `task-form` (форма записи) и @@ -53,13 +54,18 @@ flowchart TB tp --> rp["review-pipeline
10 агентов-проходов"] batch --> rp end - subgraph pm["av-dev-pm — управление продуктом, владеет docs/"] + subgraph docsp["av-dev-docs — документация, владеет docs/"] direction LR - init["init"] --> tasks["tasks"] - canon["canon"] --> tasks - session["session"] --> tasks + init["init"] + canon["canon"] docs["docs"] end + subgraph tasksp["av-dev-tasks — учёт работ"] + direction LR + session["session"] --> tasks["tasks"] + end + init --> tasks + canon --> tasks opsx["opsx:* — внешний плагин:
explore, propose, apply, archive"] git["av-dev-git: commit"] @@ -69,9 +75,13 @@ flowchart TB tp --> tasks ``` -Зависимость **односторонняя: `av-dev-pipeline` знает про `av-dev-pm`, обратно — -нет.** Управление продуктом работает в проекте без конвейера; конвейер без -канона деградирует поразрядно и говорит об этом строкой. +Зависимости **односторонние: `av-dev-pipeline` знает про `av-dev-docs` и +`av-dev-tasks`, обратно — нет.** Между собой эти двое тоже не связаны жёстко: +каждый работает без другого и зовёт соседа **через пространство имён**, а не по +пути в чужое дерево. Не разрешился вызов — плагина нет, и это исход, который +проговаривается строкой, а не поломка. То, что нужно обоим дословно — язык +проектных текстов и словарь сопровождения, — живёт домом в `shared/` и уезжает в +каждый плагин помеченной копией. ## Канон документов проекта @@ -80,7 +90,7 @@ flowchart TB `docs/` (паспорт, архитектура, база, безопасность, конвенции, разведка, ADR, ревью, задачи) и `openspec/` — **раскладка целиком, роли документов и правило единственного дома живут одним домом**: -[canon.md](av-dev-pm/skills/canon/references/canon.md). Здесь она не +[canon.md](av-dev-docs/skills/canon/references/canon.md). Здесь она не пересказывается: копия перечня путей уже расходилась с домом, и как раз в обязательных — в ней не хватало путей, чьё отсутствие `docs.py check` считает нарушением. @@ -98,9 +108,9 @@ flowchart TB «тема → её дом → что оттуда берётся» — [project-facts.md](av-dev-pipeline/skills/review-pipeline/references/project-facts.md). -Прийти в старый проект и перевести его на канон — `/av-dev-pm:canon`. Канон +Прийти в старый проект и перевести его на канон — `/av-dev-docs:canon`. Канон версионируется, и проекты повышаются по [журналу -версий](av-dev-pm/skills/canon/references/changelog.md). +версий](av-dev-docs/skills/canon/references/changelog.md). ## Подключение @@ -115,7 +125,8 @@ cd /path/to/project claude plugin marketplace add https://git.vakhrushev.me/av/dev-skills.git --scope project # плагины: scope обязателен, умолчание у команды — user, а нам нужен project -claude plugin install av-dev-pm@av-dev-skills --scope project +claude plugin install av-dev-docs@av-dev-skills --scope project +claude plugin install av-dev-tasks@av-dev-skills --scope project claude plugin install av-dev-pipeline@av-dev-skills --scope project claude plugin install av-dev-git@av-dev-skills --scope project ``` @@ -132,7 +143,8 @@ claude plugin install av-dev-git@av-dev-skills --scope project } }, "enabledPlugins": { - "av-dev-pm@av-dev-skills": true, + "av-dev-docs@av-dev-skills": true, + "av-dev-tasks@av-dev-skills": true, "av-dev-pipeline@av-dev-skills": true, "av-dev-git@av-dev-skills": true } @@ -162,7 +174,8 @@ claude plugin marketplace update av-dev-skills # 2. снимки плагинов — из каталога проекта, где они установлены cd /path/to/project -claude plugin update av-dev-pm@av-dev-skills --scope project +claude plugin update av-dev-docs@av-dev-skills --scope project +claude plugin update av-dev-tasks@av-dev-skills --scope project claude plugin update av-dev-pipeline@av-dev-skills --scope project claude plugin update av-dev-git@av-dev-skills --scope project ``` diff --git a/av-dev-docs/.claude-plugin/plugin.json b/av-dev-docs/.claude-plugin/plugin.json new file mode 100644 index 0000000..f734bd1 --- /dev/null +++ b/av-dev-docs/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "av-dev-docs", + "description": "Документация проекта: канон раскладки (CLAUDE.md плюс docs/ — паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), роли документов и правило единственного дома. Три операции одной машиной сравнения — check, adopt, upgrade — со скриптом docs.py; заведение нового проекта интервью по брифу; ведение содержимого по ходу разработки: синк после сделанной задачи, ADR промоутом из архивного design.md, записка разведки, запись дефекта в журнал ревью. Смысловое, чего скрипт не видит, судят три агента: doc-consistency, doc-code-drift, doc-wording. Задач не ведёт — это плагин av-dev-tasks, и он опционален.", + "author": { + "name": "Anton Vakhrushev", + "email": "anwinged@gmail.com" + } +} diff --git a/av-dev-pm/agents/doc-code-drift.md b/av-dev-docs/agents/doc-code-drift.md similarity index 100% rename from av-dev-pm/agents/doc-code-drift.md rename to av-dev-docs/agents/doc-code-drift.md diff --git a/av-dev-pm/agents/doc-consistency.md b/av-dev-docs/agents/doc-consistency.md similarity index 98% rename from av-dev-pm/agents/doc-consistency.md rename to av-dev-docs/agents/doc-consistency.md index ffd014a..0bf1992 100644 --- a/av-dev-pm/agents/doc-consistency.md +++ b/av-dev-docs/agents/doc-consistency.md @@ -15,11 +15,11 @@ color: yellow машина, а что человек», и её правая колонка — твой устав дословно. Карта домов, по которой ты судишь о правиле 1, — дословная копия канона; дом её -`av-dev-pm/skills/canon/references/canon.md`, раздел «Правило единственного +`av-dev-docs/skills/canon/references/canon.md`, раздел «Правило единственного дома», и правится она там. Здесь она стоит потому, что ты работаешь в репозитории проекта, где плагина может не быть вовсе. - + | Факт | Дом | | --- | --- | | поведение системы | `openspec/specs//spec.md` | diff --git a/av-dev-pm/agents/doc-wording.md b/av-dev-docs/agents/doc-wording.md similarity index 100% rename from av-dev-pm/agents/doc-wording.md rename to av-dev-docs/agents/doc-wording.md diff --git a/av-dev-pm/skills/canon/SKILL.md b/av-dev-docs/skills/canon/SKILL.md similarity index 98% rename from av-dev-pm/skills/canon/SKILL.md rename to av-dev-docs/skills/canon/SKILL.md index 43fc33d..d276202 100644 --- a/av-dev-pm/skills/canon/SKILL.md +++ b/av-dev-docs/skills/canon/SKILL.md @@ -155,7 +155,7 @@ capability), `openspec/config.yaml`. ею. Пересказ инвариантов, конвенций и правил ревью из `context` вычисти ссылкой на дом — на переводимом проекте он там почти наверняка есть; 4. переносы содержимого; -5. каталог задач — **вызови скилл `av-dev-pm:tasks`**, сценарий адаптации: он +5. каталог задач — **вызови скилл `av-dev-tasks:tasks`**, сценарий адаптации: он владеет форматом задач. Он же переименует транслитные слаги в английские и тем же проходом починит перекрёстные ссылки; 6. починка ссылок на перенесённое во всём репозитории — `docs/`, `openspec/`, @@ -172,7 +172,8 @@ capability), `openspec/config.yaml`. незаполненный канон это объявленное переходное состояние из шага 5, а не отказ. **Пункт «задачи без цели» из вложенной проверки `tasks.py` тоже остаётся** и зелёным на этом шаге не станет: цели не сочиняются адаптацией - (запрет в [tasks/references/adopt.md](../tasks/references/adopt.md)), их + (запрет записан у того, кто ведёт задачи, — сценарий адаптации скилла + `av-dev-tasks:tasks`), их проставляет человек порциями переоценки на первой сессии. Пересчитай эти пункты в докладе переходного состояния — не выдавай их за поломку и не молчи о них. diff --git a/av-dev-pm/skills/canon/references/canon.md b/av-dev-docs/skills/canon/references/canon.md similarity index 98% rename from av-dev-pm/skills/canon/references/canon.md rename to av-dev-docs/skills/canon/references/canon.md index 2dc8965..dcd77ed 100644 --- a/av-dev-pm/skills/canon/references/canon.md +++ b/av-dev-docs/skills/canon/references/canon.md @@ -24,7 +24,13 @@ ## Сопровождение и эксплуатация — целое и часть -Одна тема живёт в трёх местах канона, и путать их слова нельзя. +**Копия.** Дом — `shared/operations.md` в репозитории плагинов: словарь +делят роадмап, архитектура и тема ревью `operations`, то есть три плагина, +и ни один из трёх им не владеет. Правится дом, а не этот файл. + + + +Одна тема живёт в трёх местах, и путать их слова нельзя. **Сопровождение** — всё, чем держат проект: инструмент и сборка, процесс, выкладка, метрики и логи, инфраструктура, дежурство. **Эксплуатация** — его @@ -45,6 +51,8 @@ экране» — сопровождение: наблюдаем мы. Одни и те же метрики попадают в разные секции роадмапа, и это верно — секции отвечают на разные вопросы. + + ## Раскладка **Документ канона живёт файлом или каталогом.** `docs/security.md` и @@ -370,9 +378,10 @@ kebab-case.** Причина не эстетическая: имя файла с | 🔬 `research` | исход — знание, а не изменение | **Схемы записи здесь нет намеренно.** Какие разделы тип требует, нужна ли ему -цель и берётся ли он в спринт — скилл `tasks`: сводка в его -[SKILL.md](../../tasks/SKILL.md), раздел «Тип записи», подробно — по файлу на -тип в `tasks/references/task-<тип>.md`. Канон фиксирует **словарь**, потому что +цель и берётся ли он в спринт — скилл `av-dev-tasks:tasks`, раздел «Тип +записи», подробно — по файлу на тип в его `references/task-<тип>.md`. Ссылки в +дерево того плагина здесь нет намеренно: он ставится отдельно, и путь наружу +разрешился бы не всегда. Канон фиксирует **словарь**, потому что от него зависит, читается ли проект как продукт; схема — механика ведения задач, и второй её экземпляр разошёлся бы с первым (он и разошёлся: канон успел объявить цель у `fix` запрещённой, хотя она там необязательна). diff --git a/av-dev-pm/skills/canon/references/changelog.md b/av-dev-docs/skills/canon/references/changelog.md similarity index 100% rename from av-dev-pm/skills/canon/references/changelog.md rename to av-dev-docs/skills/canon/references/changelog.md diff --git a/av-dev-pm/skills/canon/references/language.md b/av-dev-docs/skills/canon/references/language.md similarity index 100% rename from av-dev-pm/skills/canon/references/language.md rename to av-dev-docs/skills/canon/references/language.md diff --git a/av-dev-pm/skills/canon/references/skeletons.md b/av-dev-docs/skills/canon/references/skeletons.md similarity index 99% rename from av-dev-pm/skills/canon/references/skeletons.md rename to av-dev-docs/skills/canon/references/skeletons.md index 601c832..18603a0 100644 --- a/av-dev-pm/skills/canon/references/skeletons.md +++ b/av-dev-docs/skills/canon/references/skeletons.md @@ -205,7 +205,7 @@ Верно одно из трёх: - + - **дорогой откат** — переделка стоит дороже переписывания одного файла; - **намеренный отказ** от очевидного подхода; - **пересмотр прежнего решения** — тогда у старой записи обязателен статус diff --git a/av-dev-pm/skills/canon/scripts/docs.py b/av-dev-docs/skills/canon/scripts/docs.py similarity index 100% rename from av-dev-pm/skills/canon/scripts/docs.py rename to av-dev-docs/skills/canon/scripts/docs.py diff --git a/av-dev-pm/skills/docs/SKILL.md b/av-dev-docs/skills/docs/SKILL.md similarity index 100% rename from av-dev-pm/skills/docs/SKILL.md rename to av-dev-docs/skills/docs/SKILL.md diff --git a/av-dev-pm/skills/init/SKILL.md b/av-dev-docs/skills/init/SKILL.md similarity index 99% rename from av-dev-pm/skills/init/SKILL.md rename to av-dev-docs/skills/init/SKILL.md index 53ed9b7..c01f485 100644 --- a/av-dev-pm/skills/init/SKILL.md +++ b/av-dev-docs/skills/init/SKILL.md @@ -87,7 +87,7 @@ description: "Завести новый проект — сессия вопро capability, придирки валидатора и **адреса** `docs/passport.md` и `CLAUDE.md`. Инварианты, конвенции и правило ревью не пересказывай — у них есть дома, и второй дом разойдётся с первым молча. -8. Каталог задач и первые цели — **вызови скилл `av-dev-pm:tasks`**: он владеет +8. Каталог задач и первые цели — **вызови скилл `av-dev-tasks:tasks`**: он владеет форматом целей и задач. 9. `docs.py check` из скилла `canon` — до отсутствия дрейфа. Замечания о незаполненных плейсхолдерах остаются: их закрывает не `init`, а работа. diff --git a/av-dev-pipeline/.claude-plugin/plugin.json b/av-dev-pipeline/.claude-plugin/plugin.json index da2efcb..c3ee315 100644 --- a/av-dev-pipeline/.claude-plugin/plugin.json +++ b/av-dev-pipeline/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "av-dev-pipeline", - "description": "Проведение задачи через полный цикл Spec Driven Development и конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом, независимой реализацией и обязательным триажем; плюс прогон нескольких задач разом по одной в изолированном worktree. Требует OpenSpec. Задача принимается и обычным текстом. Плагин av-dev-pm опционален: он даёт документы канона, из которых проходы читают проектную конкретику, и учёт задач; без него прогон деградирует поразрядно и называет это строкой.", + "description": "Проведение задачи через полный цикл Spec Driven Development и конвейер ревью с детерминированным гейтом, сверкой со спеками, враждебными постановками, эксплуатационным постмортемом, независимой реализацией и обязательным триажем; плюс прогон нескольких задач разом по одной в изолированном worktree. Требует OpenSpec. Задача принимается и обычным текстом. Плагины av-dev-docs и av-dev-tasks опциональны: первый даёт документы канона, из которых проходы читают проектную конкретику, второй — учёт задач; без них прогон деградирует поразрядно и называет это строкой.", "author": { "name": "Anton Vakhrushev", "email": "anwinged@gmail.com" diff --git a/av-dev-pipeline/skills/review-pipeline/SKILL.md b/av-dev-pipeline/skills/review-pipeline/SKILL.md index 02c6a1f..1f039bc 100644 --- a/av-dev-pipeline/skills/review-pipeline/SKILL.md +++ b/av-dev-pipeline/skills/review-pipeline/SKILL.md @@ -1,6 +1,6 @@ --- name: review-pipeline -description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после propose: агент review-scope выводит размер и сложность, из их максимума — метка, и раздаёт темы проходам обеих стадий. Метка правит и ревью дизайна (small — только specs; medium — плюс rubric; large — плюс architecture), и ревью кода (small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе). Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью) и из task-batch (финальная сверка)." +description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Разметка задачи идёт один раз, после propose: агент review-scope выводит размер и сложность, из их максимума — метка, и раздаёт темы проходам обеих стадий. Метка правит и ревью дизайна (small — только specs; medium — плюс rubric; large — плюс architecture), и ревью кода (small — гейт, спеки, код, триаж; medium — плюс приёмник тем; large — плюс доказательство: враждебные постановки, эксплуатационный постмортем, архитектурный проход на широком входе). Триаж обязателен всегда. Порядок прогона — граф зависимостей: гейт открывает опиниативные проходы, проходы с пометкой «держит машину» идут цепочкой, триаж — единственный сток. Проектная специфика приходит из документов канона av-dev-docs. Вызывается из task-pipeline (чекпоинты ревью) и из task-batch (финальная сверка)." --- # Конвейер ревью @@ -52,7 +52,7 @@ description: "Конвейер ревью изменения, устроенны требований. **Проект без OpenSpec этим конвейером не проверяется** — подключай OpenSpec, а не понижай прогон: ветка деградации здесь не пишется, потому что непроверенная ветка деградации хуже честного отказа. Заводить руками не надо: - `av-dev-pm:init` делает `openspec init` на новом проекте, `canon adopt` — на + `av-dev-docs:init` делает `openspec init` на новом проекте, `canon adopt` — на переводимом, и оба кладут `openspec/config.yaml` канонической формы. - **Документы канона** — см. следующий раздел. - **Проектные копии этих скиллов и агентов удаляются при установке.** Если в @@ -88,7 +88,7 @@ description: "Конвейер ревью изменения, устроенны критерий, по которому судит изменение. `adr.*`, `research.*` и `tasks/` не открывает никто. -Дом канона этой раскладки — `av-dev-pm`, `references/canon.md`, раздел «Три +Дом канона этой раскладки — `av-dev-docs`, `references/canon.md`, раздел «Три категории документов». Конвейер её **читатель**: категории и имена тем он берёт оттуда и своих не заводит. @@ -120,7 +120,7 @@ description: "Конвейер ревью изменения, устроенны читал решения, а эксплуатационный и `specs` — числа. Цена решения записана в каноне и повторяется здесь, потому что платит её конвейер: **расхождение изменения с записанным решением прогоном не ловится**, это работа сверки -документации (`av-dev-pm`, агент `doc-consistency`) на сессии между спринтами. +документации (`av-dev-docs`, агент `doc-consistency`) на сессии между спринтами. Строка об этом обязательна в границах покрытия каждого прогона. **Своя тема проекта бывает двух происхождений, и обе законны:** документ, который @@ -147,7 +147,7 @@ description: "Конвейер ревью изменения, устроенны дом для тех же фактов разошёлся бы и выглядел актуальным. **Документов канона нет вовсе** — проект не приведён к канону. Скажи это строкой -и предложи скилл `av-dev-pm:canon`: одна операция на проект против деградации на +и предложи скилл `av-dev-docs:canon`: одна операция на проект против деградации на каждой задаче. Прогон при этом не останавливается. ## Что получает каждый проход @@ -1021,7 +1021,7 @@ flowchart TD и где это лежит в документах проекта; таблица поразрядной деградации. - [references/review-levels.md](references/review-levels.md) — дом правила выбора метки: две оси, спорное вниз, чем `small` дешевле, доли как проверка правила. -- Skill `av-dev-pm:canon` — приведение проекта к канону документов. +- Skill `av-dev-docs:canon` — приведение проекта к канону документов. - [references/finding-contract.md](references/finding-contract.md) — контракт находок. - [references/promote.md](references/promote.md) — промоут находка → конвенция → правило → удаление. - [references/calibration.md](references/calibration.md) — калибровка инъекцией, вердикты keep/retune/drop. diff --git a/av-dev-pipeline/skills/review-pipeline/references/project-facts.md b/av-dev-pipeline/skills/review-pipeline/references/project-facts.md index 702d48b..8e6e665 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/project-facts.md +++ b/av-dev-pipeline/skills/review-pipeline/references/project-facts.md @@ -5,10 +5,10 @@ выдаёт правдоподобные общие места: их дорого опровергать и нечем подтверждать. Отдельного файла-брифа **нет**. Проектная конкретика живёт в документах канона -`av-dev-pm`, и проход читает их напрямую: пути жёсткие, посредник не нужен, а +`av-dev-docs`, и проход читает их напрямую: пути жёсткие, посредник не нужен, а второй дом для тех же фактов разошёлся бы и выглядел актуальным. -Определение канона — в плагине `av-dev-pm`, +Определение канона — в плагине `av-dev-docs`, `skills/canon/references/canon.md`. Здесь только карта «тема → её дом → что оттуда берётся». @@ -119,7 +119,7 @@ строка неотличима от «мы просто не стали» и перестаёт читаться на третьей задаче. **Документов канона нет вовсе** — проект не приведён к канону. Это не повод -работать вслепую: скажи об этом строкой и предложи `av-dev-pm:canon`. Одна +работать вслепую: скажи об этом строкой и предложи `av-dev-docs:canon`. Одна операция на проект против деградации на каждой задаче. ## Правило чтения diff --git a/av-dev-pipeline/skills/review-pipeline/references/review-journal.md b/av-dev-pipeline/skills/review-pipeline/references/review-journal.md index 8040b62..6e511f6 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/review-journal.md +++ b/av-dev-pipeline/skills/review-pipeline/references/review-journal.md @@ -1,7 +1,7 @@ # Журнал дефектов Артефакт проекта, а не плагина: файл живёт в репозитории — **`docs/review.md`**, -слот канона `av-dev-pm`. Здесь описано, зачем он и какой формы, потому что без +слот канона `av-dev-docs`. Здесь описано, зачем он и какой формы, потому что без него конвейер не учится: находки закрываются, а почему их не поймали — забывается, и один и тот же класс проскакивает второй раз. @@ -41,7 +41,7 @@ ## Форма записи **Это дом формы, и у него есть копия.** Скелет `docs/review.md`, который кладёт -в проект `av-dev-pm` (`skills/canon/references/skeletons.md`), повторяет её +в проект `av-dev-docs` (`skills/canon/references/skeletons.md`), повторяет её дословно — он уезжает в репозиторий и обязан там что-то говорить. Правка формы здесь **обязана** тянуть правку скелета и запись в журнал версий канона; иначе проекты продолжат писать по старой форме, а конвейер — ждать поля, которого нет. diff --git a/av-dev-pipeline/skills/review-pipeline/references/review-levels.md b/av-dev-pipeline/skills/review-pipeline/references/review-levels.md index 193225d..d224b42 100644 --- a/av-dev-pipeline/skills/review-pipeline/references/review-levels.md +++ b/av-dev-pipeline/skills/review-pipeline/references/review-levels.md @@ -94,7 +94,7 @@ костяк — гейт, спеки, код, триаж**. Разрезать задачу, обе половины которой остаются в одной метке, значит заплатить костяк дважды за ту же проверку. Резать стоит там, где разрез **снимает доказательство с большей части диффа**. -Шов и правило нарезки живут у того, кто ведёт задачи, — скилл `av-dev-pm:tasks`, +Шов и правило нарезки живут у того, кто ведёт задачи, — скилл `av-dev-tasks:tasks`, его `references/split.md`. Пути туда конвейер не выносит: за пределы своего плагина он ходит вызовом скилла, а не файлом. diff --git a/av-dev-pipeline/skills/task-batch/SKILL.md b/av-dev-pipeline/skills/task-batch/SKILL.md index dd098ab..fbc11e0 100644 --- a/av-dev-pipeline/skills/task-batch/SKILL.md +++ b/av-dev-pipeline/skills/task-batch/SKILL.md @@ -28,7 +28,7 @@ description: Проводит несколько задач разом — пл проход `review-specs` финальной сверки. Проекта без OpenSpec это касается так же, как одиночного пайплайна (см. его раздел «Предпосылки»). - **Скиллы зовутся с пространством имён**: `av-dev-pipeline:task-pipeline`, - `av-dev-pipeline:review-pipeline`, `av-dev-pm:tasks`. Короткое имя + `av-dev-pipeline:review-pipeline`, `av-dev-tasks:tasks`. Короткое имя может разрешиться в устаревшую проектную копию, и это произойдёт молча — в charter'е сабагента пиши полное имя, он твоего контекста не видит. - **Проектные копии этих скиллов и агентов при установке плагина удаляются.** @@ -39,7 +39,7 @@ description: Проводит несколько задач разом — пл `docs/database.md` и `docs/.pm.json` (ключ `migrations`). **Документов канона нет — проект к нему не приведён.** Скажи это строкой и -предложи `av-dev-pm:canon` **до первой задачи**: иначе каждая задача батча +предложи `av-dev-docs:canon` **до первой задачи**: иначе каждая задача батча заплатит поразрядной деградацией ревью, а имя основной ветки придётся угадывать. @@ -52,7 +52,7 @@ description: Проводит несколько задач разом — пл же трёх словах, что и `task-pipeline`: сделана / не доведена / оказалась крупнее задачи. - **Задачи закрывает пайплайн внутри каждого сабагента**, шагом 12 — после - коммита работы и **отдельным коммитом учёта**, вызовом Skill `av-dev-pm:tasks`. + коммита работы и **отдельным коммитом учёта**, вызовом Skill `av-dev-tasks:tasks`. Батч сам записей учёта не трогает: он не знает, чем кончилась приёмка, и дублировать закрытие ему незачем. Но грязное дерево после сабагента — **его** проблема: на нём откажут и `rebase`, и `worktree remove` (см. шаг 6). Урожай ревью батч @@ -88,7 +88,7 @@ description: Проводит несколько задач разом — пл ### 1. Прочитать набор Набор задан списком (слаги, файлы, описания) — прочитай файл каждой задачи и -связанные спеки и черновики. Сырьё (в терминах `av-dev-pm` — запись типа +связанные спеки и черновики. Сырьё (в терминах `av-dev-tasks` — запись типа `research` с пустым разделом «Вопрос») включается, но помни: сабагент проведёт его сперва через `opsx:explore`, это тяжелее и чаще упирается в вопрос. diff --git a/av-dev-pipeline/skills/task-pipeline/SKILL.md b/av-dev-pipeline/skills/task-pipeline/SKILL.md index a57cab6..dc4907f 100644 --- a/av-dev-pipeline/skills/task-pipeline/SKILL.md +++ b/av-dev-pipeline/skills/task-pipeline/SKILL.md @@ -23,7 +23,7 @@ description: "Автономно проводит одну задачу чере вырождай цикл: ветка деградации здесь не пишется, потому что непроверенная ветка деградации хуже честного отказа. - **Скиллы зовутся с пространством имён** — `av-dev-pipeline:review-pipeline`, - `av-dev-pm:docs`, `av-dev-pm:tasks`. Короткое имя может разрешиться в + `av-dev-docs:docs`, `av-dev-tasks:tasks`. Короткое имя может разрешиться в устаревшую проектную копию, и это произойдёт молча. - **Проектные копии этих скиллов и агентов удаляются при установке плагина** (`.claude/skills/` — и голые имена `task-pipeline`, `review-pipeline`, @@ -34,11 +34,11 @@ description: "Автономно проводит одну задачу чере Перед стартом прочитай `CLAUDE.md` проекта и то, на что он ссылается, если ещё не в контексте. Проектные факты, нужные ревью — инварианты, семантика гейта, -объёмы, модель угроз, прецеденты, — живут в **документах канона** `av-dev-pm`; +объёмы, модель угроз, прецеденты, — живут в **документах канона** `av-dev-docs`; карта «что где» — `references/project-facts.md` конвейера ревью. **Документов канона нет — проект к нему не приведён.** Скажи это строкой и -предложи скилл `av-dev-pm:canon`: одна операция на проект против поразрядной +предложи скилл `av-dev-docs:canon`: одна операция на проект против поразрядной деградации на каждой задаче. Работу при этом не останавливай. ## Границы: чем пайплайн не владеет @@ -47,12 +47,12 @@ description: "Автономно проводит одну задачу чере её не выбирает, не приоритизирует, не заводит и не переоценивает; если в проекте есть свой процесс управления задачами — он и решает, что брать. - **Форматом задач.** Пайплайн **не правит индексы руками и не выдумывает путь - к скрипту учёта**: он зовёт Skill `av-dev-pm:tasks`, который этим владеет + к скрипту учёта**: он зовёт Skill `av-dev-tasks:tasks`, который этим владеет (шаг 12). Закрытие как таковое — его работа, и это осознанное решение с названной ценой: **приёмщик и исполнитель совпали**. Закрытие поэтому **не окончательно** — человек на сессии возвращает задачу `reopen` с причиной, а доклад по критериям приёмки становится единственным, по чему приёмка вообще - возможна. Плагина `av-dev-pm` в проекте нет — вызов не разрешится, и тогда + возможна. Плагина `av-dev-tasks` в проекте нет — вызов не разрешится, и тогда учёт остаётся владельцу, о чём говорится в докладе. - **Заведением задач из урожая ревью.** Отложенные находки отдаются **списком** (см. шаг 8); превращать их в задачи — работа того, кто ведёт задачи проекта. @@ -113,7 +113,7 @@ description: "Автономно проводит одну задачу чере в объявленных границах. **Что остатком не является — правило живёт не здесь.** Канонический текст с обеими -оговорками — в плагине `av-dev-pm`, скилл `av-dev-pm:session`, раздел +оговорками — в плагине `av-dev-tasks`, скилл `av-dev-tasks:session`, раздел `## Вопрос, блокер, необратимое`, подраздел «Отличать вопрос от застревания». Правило принадлежит управлению задачами, потому что решает **сделана задача или вышла**, — это исход планирования, а не исполнения. **Ссылайся, не @@ -126,7 +126,7 @@ description: "Автономно проводит одну задачу чере Оба порога — стоп: первый поднимает решение до начала записи, второй даёт исход «не доведена». -Плагин `av-dev-pm` не подключён — правило не отменяется, а становится +Плагин `av-dev-tasks` не подключён — правило не отменяется, а становится осторожнее: прежде чем записать зависящее от нерешённого куда бы то ни было — в хранилище, в журнал, в витрину или наружу, — спрашивай человека. @@ -164,9 +164,9 @@ flowchart TD s7["7. opsx:apply — код, гейт, поведенческая верификация"] s8["8. ревью кода, состав по той же метки"] s9["9. opsx:archive"] - s10["10. синк документации — av-dev-pm:docs"] + s10["10. синк документации — av-dev-docs:docs"] s11["11. коммит работы — av-dev-git:commit"] - s12["12. закрыть задачу — av-dev-pm:tasks,
вторым коммитом учёта"] + s12["12. закрыть задачу — av-dev-tasks:tasks,
вторым коммитом учёта"] s1 --> triv s1 -.-> big @@ -383,7 +383,7 @@ change ``, **план разметки с шага 4** и указание, ### 10. Синк документации -Ревью выполненного — до этого шага. Затем **вызови Skill `av-dev-pm:docs`**: он +Ревью выполненного — до этого шага. Затем **вызови Skill `av-dev-docs:docs`**: он владеет содержимым документов канона и ведёт чек-лист синка. Плагина нет — шаг всё равно делается, см. ниже. @@ -394,17 +394,17 @@ change ``, **план разметки с шага 4** и указание, работает только обязательное отрицание. **Список документов и их триггеров здесь не дублируется** — он в чек-листе -скилла `av-dev-pm:docs`, и копия уже однажды разошлась с оригиналом, потеряв два +скилла `av-dev-docs:docs`, и копия уже однажды разошлась с оригиналом, потеряв два триггера. -**Плагина `av-dev-pm` в проекте нет** — путь в его дерево не разрешится ниоткуда, +**Плагина `av-dev-docs` в проекте нет** — путь в его дерево не разрешится ниоткуда, поэтому за списком иди в **свой** reference: [references/project-facts.md](../review-pipeline/references/project-facts.md) конвейера ревью перечисляет все документы канона с их предметом. Пройди по этому перечню — каждый документ получает строку, отрицание остаётся обязательным. Триггеры при этом ты знаешь хуже, и это называется в докладе строкой: «синк -сделан по перечню документов, без списка триггеров — плагина `av-dev-pm` нет». -Канона в проекте тоже нет — назови это исходом и предложи `av-dev-pm:canon`. +сделан по перечню документов, без списка триггеров — плагина `av-dev-docs` нет». +Канона в проекте тоже нет — назови это исходом и предложи `av-dev-docs:canon`. ### 11. Коммит @@ -419,7 +419,7 @@ change ``, **план разметки с шага 4** и указание, ### 12. Закрыть задачу — **после коммита, не раньше** -**Вызови Skill `av-dev-pm:tasks`** и попроси закрыть задачу как реализованную — +**Вызови Skill `av-dev-tasks:tasks`** и попроси закрыть задачу как реализованную — он владеет форматом и двигает строку из набора спринта сам. Путь к его скрипту не выясняй и индексы руками не правь: мост между плагинами — вызов скилла, а не путь. @@ -428,7 +428,7 @@ change ``, **план разметки с шага 4** и указание, оставило бы задачу закрытой без единого следа работы, если шаг 11 упадёт. **Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и -правка индексов (их имена знает `av-dev-pm`, не ты) — это правки в рабочем +правка индексов (их имена знает `av-dev-tasks`, не ты) — это правки в рабочем дереве, и оставить их незакоммиченными нельзя по трём причинам: `task-batch` следом делает `rebase` и `worktree remove`, а те откажут на грязном дереве; закрытие, не доехавшее до основной ветки, оставит задачу открытой молча; и опора «набор спринта под git diff --git a/av-dev-pm/.claude-plugin/plugin.json b/av-dev-pm/.claude-plugin/plugin.json deleted file mode 100644 index e60b434..0000000 --- a/av-dev-pm/.claude-plugin/plugin.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "av-dev-pm", - "description": "Управление продуктом: канон документов проекта (паспорт, архитектура, схема БД, безопасность, конвенции, разведка, ADR, журнал ревью), задачи и цели вместо приоритетов, спринт под одну цель с заморозкой набора, старт нового проекта интервью по брифу и приведение существующего к канону. Не выполняет задачи — этим занимается пайплайн проекта.", - "author": { - "name": "Anton Vakhrushev", - "email": "anwinged@gmail.com" - } -} diff --git a/av-dev-tasks/.claude-plugin/plugin.json b/av-dev-tasks/.claude-plugin/plugin.json new file mode 100644 index 0000000..cb2ece2 --- /dev/null +++ b/av-dev-tasks/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "av-dev-tasks", + "description": "Задачи и цели каталогом markdown-файлов: одна запись — файл в items/ плюс строка ровно в одном индексе, у записи тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение из диалога с фильтром и дедупом, разбор находок ревью в задачи, декомпозиция на независимо полезные части, гигиена полей, согласованность индексов скриптом tasks.py. Спринт под одну цель с заморозкой набора и ритуал между спринтами. Записи вычитывают два прохода: task-form (форма записи) и task-wording (язык). Канон документов ведёт плагин av-dev-docs, он опционален. Задач не выполняет — этим занимается пайплайн проекта.", + "author": { + "name": "Anton Vakhrushev", + "email": "anwinged@gmail.com" + } +} diff --git a/av-dev-pm/agents/task-form.md b/av-dev-tasks/agents/task-form.md similarity index 100% rename from av-dev-pm/agents/task-form.md rename to av-dev-tasks/agents/task-form.md diff --git a/av-dev-pm/agents/task-wording.md b/av-dev-tasks/agents/task-wording.md similarity index 100% rename from av-dev-pm/agents/task-wording.md rename to av-dev-tasks/agents/task-wording.md diff --git a/av-dev-pm/skills/session/SKILL.md b/av-dev-tasks/skills/session/SKILL.md similarity index 97% rename from av-dev-pm/skills/session/SKILL.md rename to av-dev-tasks/skills/session/SKILL.md index 81d59fd..f76a642 100644 --- a/av-dev-pm/skills/session/SKILL.md +++ b/av-dev-tasks/skills/session/SKILL.md @@ -275,9 +275,10 @@ python3 $tk reopen <слаг> --dir D --reason … # приёмка не со ## Слоты проекта Сессия не знает ни языка, ни сборки, ни CI. На часть проектного отвечает своей -структурой [канон](../canon/references/canon.md): разбор процесса (шаг 2) живёт -в `docs/review.md`, оракулы и «чем краснеет безусловно» — в семантике гейта в -`CLAUDE.md`. Остальное проект **дописывает в `CLAUDE.md`**: +структурой канон документов (его ведёт плагин `av-dev-docs`): разбор процесса +(шаг 2) живёт в `docs/review.md`, оракулы и «чем краснеет безусловно» — в +семантике гейта в `CLAUDE.md`. Пути известны, ссылки в чужое дерево нет: канон +ставится отдельно, а без него оба файла всё равно читаются по имени. Остальное проект **дописывает в `CLAUDE.md`**: 1. **Пайплайн задачи** — чем задача выполняется и что входит в его определение готовности. Сессия требует только форму: пайплайн пройден + критерии приёмки diff --git a/av-dev-pm/skills/session/references/cadence.md b/av-dev-tasks/skills/session/references/cadence.md similarity index 100% rename from av-dev-pm/skills/session/references/cadence.md rename to av-dev-tasks/skills/session/references/cadence.md diff --git a/av-dev-pm/skills/session/references/sprint.md b/av-dev-tasks/skills/session/references/sprint.md similarity index 99% rename from av-dev-pm/skills/session/references/sprint.md rename to av-dev-tasks/skills/session/references/sprint.md index 2249a12..e607515 100644 --- a/av-dev-pm/skills/session/references/sprint.md +++ b/av-dev-tasks/skills/session/references/sprint.md @@ -117,7 +117,7 @@ flowchart TD пайплайна, после коммита. Порядок: 1. пайплайн доводит задачу до коммита; -2. **после коммита** зовёт `Skill av-dev-pm:tasks` и закрывает задачу +2. **после коммита** зовёт `Skill av-dev-tasks:tasks` и закрывает задачу (`close --implemented`); строка уходит из `SPRINT.md`; 3. **докладывает исход и по каждому критерию — оракул и наблюдаемый исход.** Это доклад приёмщику, а не отметка «принято». diff --git a/av-dev-pm/skills/tasks/SKILL.md b/av-dev-tasks/skills/tasks/SKILL.md similarity index 96% rename from av-dev-pm/skills/tasks/SKILL.md rename to av-dev-tasks/skills/tasks/SKILL.md index c035860..98c7617 100644 --- a/av-dev-pm/skills/tasks/SKILL.md +++ b/av-dev-tasks/skills/tasks/SKILL.md @@ -60,9 +60,10 @@ description: Ведение задач и целей как каталога mar ## Раскладка -Каталог задач — **`docs/tasks`, жёстко**: это часть -[канона документов](../canon/references/canon.md), и подгоняется под него -проект, а не наоборот. +Каталог задач — **`docs/tasks`, жёстко**: это часть канона документов, и +подгоняется под него проект, а не наоборот. Канон ведёт другой плагин +(`av-dev-docs`), и **путь известен скиллу сам** — ссылки в чужое дерево здесь +нет намеренно: скилл работает и там, где того плагина не поставили. ``` docs/tasks/ @@ -194,7 +195,7 @@ stateDiagram-v2 часть кода мы трогаем». **Целью не становится работа, которой держат проект.** Состав перечислен -[в каноне](../canon/references/canon.md), раздел «Сопровождение и эксплуатация»; +[в словаре сопровождения](references/operations.md); на вопрос «что приложение будет уметь» ничто из него не отвечает. Им отведена отдельная секция роадмапа, чтобы они были видны в том же экране и при этом не читались как возможности продукта. @@ -206,11 +207,12 @@ stateDiagram-v2 секции отвечают на разные вопросы. **Сопровождение и эксплуатация — целое и часть**, а не синонимы, и та же тема -живёт ещё в двух местах канона: разделе «Эксплуатация» в `architecture.md` и -теме ревью `operations`. Словарь у всех трёх общий и живёт одним домом — -[canon.md](../canon/references/canon.md), раздел «Сопровождение и эксплуатация». -Пересказывать его здесь нельзя: три перечня «чем держат проект» уже разъезжались -на «метриках и логах» против «мониторинга». +живёт ещё в двух местах: разделе «Эксплуатация» в `architecture.md` и теме ревью +`operations`. Словарь у всех трёх общий, дом у него один — `shared/operations.md` +в репозитории плагинов, — а здесь лежит дословная копия: +[references/operations.md](references/operations.md). Пересказывать его своими +словами нельзя: три перечня «чем держат проект» уже разъезжались на «метриках и +логах» против «мониторинга». Секция выбирается так: очередь значима и обоснована прозой — `Запланировано`; тянется долго и очереди не имеет — `Направления`; не про приложение, а про то, @@ -329,11 +331,12 @@ stateDiagram-v2 **Предметно, но без усложнения.** Текст задачи читает человек, который решает, брать её или нет, и делает это по строке индекса и одному экрану тела. -Язык — общий для всех проектных текстов, и живёт он одним файлом: -[../canon/references/language.md](../canon/references/language.md) -(информационный стиль, применённый к задачам и документам канона; там же таблицы -англицизмов и жаргона и то, что из стиля отброшено намеренно). Задаче он даёт -четыре требования, которые нарушаются чаще прочих: +Язык — общий для всех проектных текстов, и дом у него один, +`shared/language.md` в репозитории плагинов; здесь лежит дословная копия: +[references/language.md](references/language.md) (информационный стиль, +применённый к задачам и документам канона; там же таблицы англицизмов и жаргона +и то, что из стиля отброшено намеренно). Задаче он даёт четыре требования, +которые нарушаются чаще прочих: - **глагол вместо отглагольного существительного**: «обработчик не проверяет владельца», а не «проверка владельца не осуществляется»; @@ -514,7 +517,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап **одним проходом вместе с починкой перекрёстных ссылок**, а не по одному слагу. Если переводить надо не только задачи, а весь `docs/` — это скилл -`av-dev-pm:canon`, и он зовёт этот сценарий сам на своём шаге. +`av-dev-docs:canon`, и он зовёт этот сценарий сам на своём шаге. ### Декомпозиция и штурм сырья @@ -618,7 +621,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап - **Каталог задач — `docs/tasks`, жёстко**, и `--dir` передаётся явно всегда: раскладка канона одинакова во всех проектах, и искать больше нечего. Каталога нет — код 3 и вопрос человеку; `init` заводит его **только** когда проект - действительно новый, а перевод чужой раскладки делает `av-dev-pm:canon`. + действительно новый, а перевод чужой раскладки делает `av-dev-docs:canon`. У скрипта поиск вверх по дереву ещё жив — он для непереведённых проектов, и полагаться на него скилл не должен: молча найденный чужой каталог это дрейф. - **Настройки живут в `docs/.pm.json`**, ключ `tasks`: **имена** файлов и @@ -636,7 +639,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап переменной не дотянутся. Мост — **вызов скилла через пространство имён**, а не путь: -> Чужой контекст зовёт `Skill av-dev-pm:tasks` и называет, что нужно сделать +> Чужой контекст зовёт `Skill av-dev-tasks:tasks` и называет, что нужно сделать > («закрой задачу `<слаг>`, реализована»). Скилл разрешает свой > `$CLAUDE_PLUGIN_ROOT` сам. Путь наружу не выносится вовсе. diff --git a/av-dev-pm/skills/tasks/references/adopt.md b/av-dev-tasks/skills/tasks/references/adopt.md similarity index 98% rename from av-dev-pm/skills/tasks/references/adopt.md rename to av-dev-tasks/skills/tasks/references/adopt.md index 5797f91..c2af1a6 100644 --- a/av-dev-pm/skills/tasks/references/adopt.md +++ b/av-dev-tasks/skills/tasks/references/adopt.md @@ -5,7 +5,7 @@ после неё проект живёт скиллами `tasks` и `session`. **Это часть приведения проекта к канону.** Раскладку `docs/` целиком ведёт скилл -`av-dev-pm:canon`; он же зовёт этот сценарий на шаге «каталог задач», потому что +`av-dev-docs:canon`; он же зовёт этот сценарий на шаге «каталог задач», потому что форматом задач владеет `tasks`, а не `canon`. Отдельно сценарий вызывается, когда переводить надо **только** задачи. diff --git a/av-dev-pm/skills/tasks/references/from-review.md b/av-dev-tasks/skills/tasks/references/from-review.md similarity index 100% rename from av-dev-pm/skills/tasks/references/from-review.md rename to av-dev-tasks/skills/tasks/references/from-review.md diff --git a/av-dev-tasks/skills/tasks/references/language.md b/av-dev-tasks/skills/tasks/references/language.md new file mode 100644 index 0000000..71f0ea3 --- /dev/null +++ b/av-dev-tasks/skills/tasks/references/language.md @@ -0,0 +1,211 @@ +# Язык проектных текстов + +**Копия.** Дом — `shared/language.md` в репозитории плагинов; язык общий для +документов канона и для задач, и потому не принадлежит ни одному плагину. +Правится дом, а не этот файл: расхождение ловит `copies.py` на гейте коммита. + + + +Правила — для всего, что пишется словами: задачи и цели, документы канона, +решения ADR, записки разведки, сообщения коммитов. Не для кода и не для +сообщений программы пользователю — там свои конвенции проекта. + +Основа — **информационный стиль** Максима Ильяхова ([учебник +бюро](https://bureau.ru/projects/book-text/), книга «Пиши, сокращай»). Он +написан для рекламы, статей и писем, поэтому взят не целиком. + +## Зачем он здесь + +Проектный текст читают в двух положениях, и оба неудобные: **выбирают, брать ли +задачу**, глядя в строку индекса и один экран тела; и **возвращаются через +квартал**, не помня контекста. Оба положения наказывают одно и то же — слова, не +несущие сведений. Информационный стиль ровно про это, и его польза здесь не +эстетическая: текст, из которого нельзя достать факт, заставляет открывать код, +а это и есть цена, которой мы избегаем. + +## Что взято сверх правил вычитки + +Эти три требования судит человек, а не проход вычитки: находка по ним требует +увидеть текст целиком, а не фразу. + +**Полезное действие.** У каждого текста есть вопрос, на который он отвечает, и +читатель, который этот вопрос задаёт. Не отвечает — не пишется. У задачи это +«зачем она нужна» и «что станет наблюдаемо иначе»; у документа канона — его +собственный вопрос («что это за система», «как сложено», «почему так решили»). +Текст, который не отвечает ни на чей вопрос, сокращается до нуля — это законный +исход правки. + +**Параллельность.** Однородное пишется одинаково: пункты списка — одной +грамматической формой, разделы одного вида — одним порядком, заголовки одного +уровня — одним типом фразы. Разнобой читатель принимает за разницу по существу и +ищет её. + +**Заголовок работает.** Заголовок называет содержание раздела, а не тему +вообще: «Что проверяет `check`», а не «О проверках». Заголовков ставится +столько, чтобы длинный текст можно было просматривать, а не только читать +подряд. + +## Что отброшено намеренно + +Инфостиль написан для текстов, где читателя надо удержать. Проектный текст +читают потому, что надо, и держать его нечем. Отсюда три расхождения: + +- **Парцелляция и рубленые фразы — нет.** Приём «Коротко. Ещё короче. Вот так» + ломает причинную связь, а в решении и в задаче ценность именно в ней: + «поэтому», «иначе», «раз так» несут смысл и остаются. +- **Не всякое вводное — мусор.** «Если», «иначе», «при таком-то условии», + «в отличие от» — это условия и противопоставления, то есть сведения. Режутся + вводные, которые не меняют смысл предложения. +- **Скобки и точка с запятой остаются.** В технической записи скобки несут + уточнение — имя команды, единицы, слаг, — и запрет на них удлинил бы текст, а + не сократил. Запрет на многоточие принимаем: в проектном тексте оно значит + «дописать позже», и такой текст лучше не публиковать. + +И общее: инфостиль призывает «снять корону с себя и надеть на читателя». Здесь +читатель — **ты сам через квартал** и тот, кто возьмёт задачу. Писать для них +значит называть состояние и остаток, а не пересказывать, как было интересно +разбираться. + + + +## Правила + + + +У каждого правила названа причина: она же говорит, где правило **не** +применяется. + +1. **Глагол вместо отглагольного существительного, активный залог.** «Обработчик + не проверяет владельца», а не «проверка владельца не осуществляется»; + «скрипт переписывает индекс», а не «индекс переписывается скриптом». + Отглагольное существительное прячет того, кто действует, — а в техническом + тексте важен именно он. Страдательный залог **остаётся**, когда деятель + неизвестен или неважен: «файл удаляется» верно, если удаляет любая из трёх + команд. + +2. **Факт вместо оценки.** «Время ответа доходит до 800 мс», а не «работает + медленно»; «тело 40 МиБ держит блокировку 5 секунд», а не «большие тела + тормозят». Оценка допустима, когда факт стоит рядом, в той же фразе. Без + факта это настроение, а не сведение, — и находка тем ценнее, что оценку + потом не проверить. + +3. **Стоп-слова.** Канцелярит (является, осуществляется, в целях, в рамках, + данный, вышеуказанный), вводные-паразиты (в общем, как известно, стоит + отметить), усилители (очень, крайне, достаточно, абсолютно, максимально), + синонимы одного качества («понятный и простой»), неопределённое + (соответствующий, определённый, некоторый). + + Проверка одна: **вычеркни слово — смысл изменился, оставляй.** И осторожно с + вводными: «если», «иначе», «при таком-то условии», «в отличие от» несут + условие и противопоставление, то есть сведения, — их не трогают. + +4. **Одна мысль — одно предложение.** Предложение с двумя независимыми + утверждениями делится. **Причинную связь не режут**: «поэтому», «иначе», «раз + так» — смысл, а не длина; рубленые фразы ради краткости тут вредят. + + **Поля меты не делятся.** «Зачем» в мете задачи по формату — одно + предложение: оно повторяется строкой индекса, и второму там не поместиться. + Тесно — сокращают, но не делят. То же с любым полем вида `- **Имя:** …`. + +5. **Англицизм, у которого есть живое русское слово, заменяется.** + + | Калька | Русский аналог | + | --- | --- | + | флоу | поток, процесс, сценарий | + | фикс, зафиксить | исправление, исправить, починить | + | чекать | проверять | + | апрув, заапрувить | согласование, согласовать | + | best-effort | по возможности | + | кейс | случай, сценарий | + | перформанс | производительность | + | матчинг, смэтчить | сопоставление, сопоставить | + | зарелизить | выпустить, выложить | + | отрефакторить | переписать, разделить, убрать второй путь | + + Насильно не переводится то, что является **именем вещи**: термины технологий + и протоколов (`SQL`, `API`, `CSV`, `N+1`, `IDOR`), имена классов, методов, + полей, таблиц и команд, слаг, а также термин, у которого нет точного русского + эквивалента и который в команде уже прижился. + + Цель — простой и точный текст, а не пуризм. Русский аналог звучит коряво или + искажает смысл — остаётся термин. + +6. **Слово из своего словаря не трогается — список закрыт.** Оговорка «термин + прижился» без списка проверяема на глаз и потому не проверяема: прижившимся + выглядит любое слово, встреченное трижды. + + | Термин | Что называет | + | --- | --- | + | интейк | заведение записи с фильтром и дедупом: «заведение» называет создание файла, слить их — смешать две операции | + | триаж | стадия конвейера, сводящая находки в решение | + | провенанс | обязательное свойство числа: чем и при каких условиях получено. «Источник» рядом называет саму запись, а не свойство | + | дедуп, дедупликация | сверка нового против уже лежащего | + | чек-лист | перечень, по которому идут сверху вниз, называя исход каждой строки | + | дифф, `--base` | разница между состояниями в git | + | промпт | текст, которым зовут модель | + | change, capability, spec | сущности OpenSpec, имена вещей чужого инструмента | + | generative, applicative | роды проходов ревью, вводятся определением по месту | + + **Список закрыт.** Слово не отсюда и не из таблицы имён вещей выше — находка, + а не «принятый стиль»: у него либо есть живой русский аналог, либо оно + требует ввода одной строкой при первом употреблении. + + Отсюда же читается снятое. Эти слова из текстов убраны, и возвращать их не + надо: **конфляция** (смешение), **декорреляция** (разведённость, разведён с + кем-то), **непоймание** (почему не поймали), **эвал-сет** (проверочный + набор), **гайд** (руководство). Каждое было латинизмом или калькой при живом + русском слове, и каждое к моменту снятия жило в трёх-шести файлах разом — то + есть выглядело словарём, не будучи им. + +7. **Жаргон и метафоры заменяются прямым называнием.** Автору образ понятен, + читателю — нет. + + | Метафора-жаргон | Прямо | + | --- | --- | + | рычаг (кэша, отбора) | условие отбора, параметр | + | навешен не на тот счётчик | завязан не на тот счётчик | + | переширокий матчинг по имени | слишком грубое сопоставление по имени, слишком много слабых совпадений | + | костыль | временное решение, обходной путь — и в чём именно | + | просело, отвалилось | стало медленнее на столько-то, перестало отвечать | + + Проверка: **фраза требует, чтобы читатель додумал образ, — заменяется + буквальным описанием того, что происходит.** + +8. **Термин, которого нет в документах проекта, вводится одной строкой или не + употребляется.** Термин, не встречающийся ни в паспорте, ни в архитектуре, ни + в конвенциях, — свой словарь у отдельной записи, а это самый дешёвый способ + сделать беклог нечитаемым для того, кто вернётся к нему через квартал. + Заменять незнакомый термин догадкой нельзя: догадка о предметной области + дороже непонятного слова, потому что выглядит понятной. + + **Слово, занятое в другом смысле, — то же нарушение.** Термин, который в + одном документе проекта значит одно, а здесь другое, ломает оба. + +9. **Имя файла — английское слово по сути, а не транслит.** `queue-as-table`, а + не `ochered-tablicej`; `move-parse-strict`, а не `razbor-hoda`. Транслит + нечитаем тому, кто ищет по смыслу, и не сокращается, а имя стоит в ссылках, + коммитах и путях, которые набирают руками. Переименование — **перенос ссылок + одним проходом**, а не правка одного файла. + + + +## Порог правки + + + +**Правка без нарушенного правила не делается.** Текст, переписанный «чтобы +звучало лучше», обесценивает список замечаний: когда половина из них вкусовая, +перестают читать весь список, и вместе с ним пропадают настоящие находки. +Сомневаешься — не правь. Формулировка, которая просто **не твоя**, — не находка. + +**Систематичность нарушения — не довод в его пользу.** Одна и та же ошибка в +пяти файлах не становится «принятым стилем»: чаще это значит, что правило не +применялось вовсе, — и находка тем важнее. «Так сделано везде» годится как +основание для **одной находки на весь набор** («правило N нарушено в пяти +записях, перечень: …»), но не как основание промолчать. Принятым считается +только то, что назвал зовущий или что записано в конвенциях проекта. + + + +И обратное: язык правится **по ходу той операции, которая записи касается**. +Беклог не переписывают ради языка. diff --git a/av-dev-tasks/skills/tasks/references/operations.md b/av-dev-tasks/skills/tasks/references/operations.md new file mode 100644 index 0000000..8a7a85a --- /dev/null +++ b/av-dev-tasks/skills/tasks/references/operations.md @@ -0,0 +1,34 @@ +# Сопровождение и эксплуатация + +**Копия.** Дом — `shared/operations.md` в репозитории плагинов. Словарь общий для +роадмапа, архитектуры и темы ревью `operations`, и не принадлежит ни одному из +трёх — правится дом, а не этот файл. + +Скиллу задач он нужен для секции `Сопровождение` в `ROADMAP.md`: она отвечает не +на «что приложение будет уметь», а на «чем его держат», и путать эти два вопроса +нельзя. + + + +Одна тема живёт в трёх местах, и путать их слова нельзя. + +**Сопровождение** — всё, чем держат проект: инструмент и сборка, процесс, +выкладка, метрики и логи, инфраструктура, дежурство. **Эксплуатация** — его +часть: работа системы на проде. Целое и часть, и никогда наоборот. + +| Место | Уровень | Что там | +| --- | --- | --- | +| `ROADMAP.md`, секция `Сопровождение` | план | **работы**, которые собираемся делать: цели и их задачи | +| `architecture.md`, раздел «Эксплуатация» | состояние | **как устроено сейчас**: где работает, что рядом, кто перезапускает | +| тема ревью `operations` | оптика | **чем проверяем**: «это упало через неделю на проде» | + +Слово **«поддержка» не употребляется вовсе** — в нём слышится помощь +пользователю, а это другая работа. + +**Граница с возможностями проходит по тому, кто наблюдает.** «Приложение +сообщает о своём состоянии» — возможность приложения, её место среди прочих +целей: наблюдает пользователь сервиса. «Дежурный видит состояние на одном +экране» — сопровождение: наблюдаем мы. Одни и те же метрики попадают в разные +секции роадмапа, и это верно — секции отвечают на разные вопросы. + + diff --git a/av-dev-pm/skills/tasks/references/split.md b/av-dev-tasks/skills/tasks/references/split.md similarity index 100% rename from av-dev-pm/skills/tasks/references/split.md rename to av-dev-tasks/skills/tasks/references/split.md diff --git a/av-dev-pm/skills/tasks/references/task-chore.md b/av-dev-tasks/skills/tasks/references/task-chore.md similarity index 100% rename from av-dev-pm/skills/tasks/references/task-chore.md rename to av-dev-tasks/skills/tasks/references/task-chore.md diff --git a/av-dev-pm/skills/tasks/references/task-feature.md b/av-dev-tasks/skills/tasks/references/task-feature.md similarity index 100% rename from av-dev-pm/skills/tasks/references/task-feature.md rename to av-dev-tasks/skills/tasks/references/task-feature.md diff --git a/av-dev-pm/skills/tasks/references/task-fix.md b/av-dev-tasks/skills/tasks/references/task-fix.md similarity index 100% rename from av-dev-pm/skills/tasks/references/task-fix.md rename to av-dev-tasks/skills/tasks/references/task-fix.md diff --git a/av-dev-pm/skills/tasks/references/task-format.md b/av-dev-tasks/skills/tasks/references/task-format.md similarity index 100% rename from av-dev-pm/skills/tasks/references/task-format.md rename to av-dev-tasks/skills/tasks/references/task-format.md diff --git a/av-dev-pm/skills/tasks/references/task-goal.md b/av-dev-tasks/skills/tasks/references/task-goal.md similarity index 96% rename from av-dev-pm/skills/tasks/references/task-goal.md rename to av-dev-tasks/skills/tasks/references/task-goal.md index 71eae5a..9fb2b1b 100644 --- a/av-dev-pm/skills/tasks/references/task-goal.md +++ b/av-dev-tasks/skills/tasks/references/task-goal.md @@ -38,8 +38,8 @@ 1. **Проверить, что это возможность, а не работа.** Работа, которой держат проект, на вопрос «что приложение будет уметь» не отвечает; состав перечислен - [в каноне](../../canon/references/canon.md), раздел «Сопровождение и - эксплуатация». Ей отведена секция `Сопровождение` — там она видна в том же + [в словаре сопровождения](operations.md). Ей отведена секция + `Сопровождение` — там она видна в том же экране и не читается как обещание продукта. Граница проходит по тому, **кто наблюдает**: «приложение сообщает о своём состоянии» — возможность, «дежурный видит diff --git a/av-dev-pm/skills/tasks/references/task-research.md b/av-dev-tasks/skills/tasks/references/task-research.md similarity index 100% rename from av-dev-pm/skills/tasks/references/task-research.md rename to av-dev-tasks/skills/tasks/references/task-research.md diff --git a/av-dev-pm/skills/tasks/scripts/tasks.py b/av-dev-tasks/skills/tasks/scripts/tasks.py similarity index 99% rename from av-dev-pm/skills/tasks/scripts/tasks.py rename to av-dev-tasks/skills/tasks/scripts/tasks.py index e301425..5997b7f 100755 --- a/av-dev-pm/skills/tasks/scripts/tasks.py +++ b/av-dev-tasks/skills/tasks/scripts/tasks.py @@ -77,7 +77,7 @@ goal | feature | fix | chore | research, по-английски, как и пр Каталог задач: `--dir` (обязан быть внутри рабочего каталога) → `docs/tasks` вверх от текущего каталога. Прежние раскладки (`tasks`, `doc/tasks`) читаются, -пока живы непереехавшие проекты; переводит их скилл av-dev-pm:canon. +пока живы непереехавшие проекты; переводит их скилл av-dev-docs:canon. Коды выхода (единый словарь, на нём ветвятся скиллы): @@ -484,7 +484,7 @@ def _validate_config(data: dict, path: Path) -> dict: if "plan" in unknown: raise Env(f"{path}: ключ «plan» переименован в «roadmap»," f" а PLAN.md — в ROADMAP.md. Повысь проект скиллом" - f" av-dev-pm:canon (upgrade), а не правь ключ в одиночку:" + f" av-dev-docs:canon (upgrade), а не правь ключ в одиночку:" f" файл и ссылки на него переезжают вместе с ним") if unknown: raise Env(f"{path}: неизвестные ключи: {', '.join(sorted(unknown))}" @@ -567,7 +567,7 @@ def resolve_layout(explicit: str | None) -> Layout: break # выше корня репозитория не ищем raise Env("каталог задач не найден: ни --dir, ни docs/tasks вверх от" f" {here}. По канону путь всегда docs/tasks; чужую раскладку" - " переводит скилл av-dev-pm:canon, новый проект —" + " переводит скилл av-dev-docs:canon, новый проект —" " tasks.py init --dir docs/tasks") diff --git a/shared/operations.md b/shared/operations.md new file mode 100644 index 0000000..557b343 --- /dev/null +++ b/shared/operations.md @@ -0,0 +1,35 @@ +# Сопровождение и эксплуатация + +**Это дом.** Словарь «чем держат проект» назван в трёх местах трёх разных +плагинов: секция `Сопровождение` в роадмапе (`av-dev-tasks`), раздел +«Эксплуатация» в `architecture.md` (`av-dev-docs`) и тема ревью `operations` +(`av-dev-pipeline`). Ни один из трёх им не владеет, поэтому дом стоит снаружи, а +плагины везут копии. + +Три перечня «чем держат проект» уже разъезжались — на «метриках и логах» против +«мониторинга», — и разъехались молча. Отсюда дословная копия вместо ссылки. + + + +Одна тема живёт в трёх местах, и путать их слова нельзя. + +**Сопровождение** — всё, чем держат проект: инструмент и сборка, процесс, +выкладка, метрики и логи, инфраструктура, дежурство. **Эксплуатация** — его +часть: работа системы на проде. Целое и часть, и никогда наоборот. + +| Место | Уровень | Что там | +| --- | --- | --- | +| `ROADMAP.md`, секция `Сопровождение` | план | **работы**, которые собираемся делать: цели и их задачи | +| `architecture.md`, раздел «Эксплуатация» | состояние | **как устроено сейчас**: где работает, что рядом, кто перезапускает | +| тема ревью `operations` | оптика | **чем проверяем**: «это упало через неделю на проде» | + +Слово **«поддержка» не употребляется вовсе** — в нём слышится помощь +пользователю, а это другая работа. + +**Граница с возможностями проходит по тому, кто наблюдает.** «Приложение +сообщает о своём состоянии» — возможность приложения, её место среди прочих +целей: наблюдает пользователь сервиса. «Дежурный видит состояние на одном +экране» — сопровождение: наблюдаем мы. Одни и те же метрики попадают в разные +секции роадмапа, и это верно — секции отвечают на разные вопросы. + +