diff --git a/dist/mappa-brainstorm-promote.skill b/dist/mappa-brainstorm-promote.skill index d1c29cb..6ca3d03 100644 Binary files a/dist/mappa-brainstorm-promote.skill and b/dist/mappa-brainstorm-promote.skill differ diff --git a/skills/mappa-brainstorm-promote/SKILL.md b/skills/mappa-brainstorm-promote/SKILL.md index e20daf4..674f71e 100644 --- a/skills/mappa-brainstorm-promote/SKILL.md +++ b/skills/mappa-brainstorm-promote/SKILL.md @@ -1,466 +1,276 @@ --- name: mappa-brainstorm-promote author: ours -version: 1.5.0 +version: 1.6.0 description: > - Finalize a matured brainstorm buffer on the boss's desk - (~/projects/.workshop/.brainstorm/): ask routing (workshop-meta → local - .wiki/concepts/, domain → target project wiki via knowledge_ingest, - mappa-service → mappa-борд (create — карв-аут без лиза wiki:2660), skill → - claude-skills skeleton), - extract action-items into target .tasks, create pointers + review umbrella - for impl tasks, archive the buffer. Старое имя — триггер-синоним: - workshop-promote-brainstorm. Location-agnostic: fires from ANY folder; all - paths resolve to ~/projects/.workshop/ regardless of CWD. Triggers (user): - «промоутни брейнсторм», «finalize », «выкати в вики», «promote - ». + Finalize a matured brainstorm storm-entity in mappa (type=storm, in ANY + project): read buffer → route (workshop-meta → .workshop wiki; domain → + target project wiki; skill → ~/projects/skills skeleton) → promote via + mcp__mappa__storm_promote (atomic buffer → wiki-страница + archive, решение 7) + → extract action-items into target tasks (mcp__mappa__task_create, карв-аут) + → review umbrella → covering letter. Старое имя — триггер-синоним: + workshop-promote-brainstorm. Project-agnostic: storm lives where it is led, + not only in .workshop; file channels (.brainstorm/.archive) are read-only + legacy (импортированы в mappa). Triggers (user): «промоутни брейнсторм», + «finalize », «выкати в вики», «promote ». --- # mappa-brainstorm-promote -Финализация созревшего брейнсторм-буфера на столе босса (`~/projects/.workshop/`) — **процедура** (линейная: от чтения буфера до архивации), не цикл в смысле повторения: запускается явно на финальном буфере и доводит его до конца (промоушен + таски + архив). В форкфлоу встаёт между работой (`mappa-task-work`) и финишем (`mappa-closing-ritual`). Четыре ветки маршрутизации: +Финализация созревшего шторм-буфера, который живёт **как mappa storm-сущность** +(type=storm, status=buffer) в любом проекте — **процедура** (линейная: от чтения +буфера до промоута и тасок), не цикл: запускается явно на финальном буфере и +доводит его до конца. В форкфлоу встаёт между работой (`mappa-task-work`) и +финишем (`mappa-closing-ritual`). -> **Location-agnostic.** Скил триггерится из любой папки — босс-штормы -> происходят где угодно, запись живёт на столе. Все относительные пути ниже -> (`.brainstorm/`, `.archive/`, `.wiki/`, `index.md`) разрешаются относительно -> `~/projects/.workshop/` **независимо от CWD**; git-команды явно указывают -> `-C ~/projects/.workshop`. +> **Project-agnostic.** Шторм ведётся там, где его ведут, — не только в +> `.workshop/`. Скил триггерится из любой папки; буфер ищется в mappa +> (`entity_search` type=storm), а не на диске. Файловые `.brainstorm/`/ +> `.archive/` — read-only легаси: их содержимое уже импортировано в mappa +> storm-сущности (решение 15, флип), новые записи в файлы не делаются. -- **workshop-meta** → локальный `.wiki/concepts/` (методология самой зоны). -- **domain** → глобал через `mcp__projects-meta__knowledge_ingest` в `~/projects//.wiki/`. -- **mappa-service** → сервисные борды (mappa, .common, …): таски/вики-сущности через `mcp__mappa__task_create`/`wiki_create` (**create — карв-аут без лиза**, wiki:2660; update — version+409); pointers-таска НЕ нужна, если спека уже в вики проекта (wiki:NNNN); review-umbrella — сервисная таска; covering-письмо в инбокс цели. -- **skill** → `~/projects/claude-skills/skills//SKILL.md` (только шапка + пустой каркас тела, локальный коммит без push/install/build-hermes). +Три ветки маршрутизации (спросить пользователя): -Буфер уезжает в `.archive/`. Action-items уходят тасками в target-проект. **Всегда, при любом маршруте, в воркшоп-вики остаётся summary-страница.** +- **workshop-meta** → промоут в `.workshop`: wiki-страница в вики зоны + (методология самой зоны). +- **domain** → промоут в целевой проект: wiki-страница (спека) в его вики + + импл-таски + review-umbrella. +- **skill** → каркас скила в `~/projects/skills/skills//SKILL.md` + (только шапка + пустой каркас тела, локальный коммит без push/install). + +Промоут контента — **всегда через `mcp__mappa__storm_promote`**: атомарно +создаёт wiki-страницу (slug из шторма, body сохраняется) в проекте из вызова и +переводит шторм в `archive` (номер/slug стабильны, решение 20; рёбра parent_of, +событие `storm.promoted`). **Никаких git mv и файловых архивов.** Action-items +уходят тасками в target-проект через `mcp__mappa__task_create` (карв-аут без +лиза, #1054; последовательно, не батчем). ## When to use -- «промоутни брейнсторм», «finalize », «выкати в вики», «promote ». -- Пользователь явно ссылается на `.workshop/.brainstorm/.md` как на готовый к промоушену. +- «промоутни брейнсторм», «finalize », «выкати в вики», «promote + ». +- Пользователь ссылается на storm-сущность (storm:N) или на тему шторма, + которая созрела и готова к промоушену. ## Inputs -- Путь `.brainstorm/.md` или просто ``. -- Для skill-ветки дополнительно: `` нового скила (если не указан — спросить, предложить производное от topic). +- Storm-реф `storm:N` или `` (slug/тема шторма) + project (если шторм + не в текущем проекте — спросить). +- Для skill-ветки дополнительно: `` нового скила (если не указан — + спросить, предложить производное от topic). ## Decision flow ``` -.brainstorm/.md +storm-сущность в mappa (type=storm, status=buffer) │ ▼ - read + summarize (1–2 paragraphs) + find + read (entity_search type=storm → entity_get полный body) │ ▼ ask: workshop-meta or domain or skill? │ │ │ │ ▼ ▼ │ ask: target proj ask: + check - │ │ ~/projects/claude-skills/ + │ │ ~/projects/skills/ │ ┌─────┴─────┐ skills// NOT exists │ ▼ ▼ │ - │ file channel service channel │ - │ (.tasks/) (mappa-борд) │ + │ storm_promote storm_promote dialog: description (trigger contract) + │ (project=.workshop) (project=) │ + │ │ │ ▼ + │ │ │ preview + confirm │ │ │ │ - │ ▼ ▼ ▼ - │ knowledge_ingest mcp__mappa__wiki_create dialog: description (trigger contract) - │ │ (карв-аут, wiki:2660) │ - │ │ │ ▼ - │ │ │ preview + confirm - │ │ │ │ - │ │ │ ▼ - │ │ │ mkdir + Write SKILL.md - │ │ │ (header + empty 6-section skeleton) - │ │ │ │ - │ │ │ ▼ - │ │ │ git add + commit in claude-skills/ - │ │ │ (local, no push, no install.sh, no build-hermes) - │ │ │ │ - └────────┴───────────┴─────────────────┘ + │ │ │ ▼ + │ │ │ mkdir + Write SKILL.md + │ │ │ (header + empty 6-section skeleton) + │ │ │ │ + │ │ │ ▼ + │ │ │ git add + commit in ~/projects/skills/ + │ │ │ (local, no push, no install.sh) + │ │ │ │ + └────────┴───────────┴────────────┘ │ ▼ - parse action-items + (for skill: prepend 3 baselines) + parse action-items from storm body │ ▼ - for each: tasks_create (ПОСЛЕДОВАТЕЛЬНО, не батчем) - [file: mcp__projects-meta__tasks_create | service: mcp__mappa__task_create] + for each: mcp__mappa__task_create (ПОСЛЕДОВАТЕЛЬНО, не батчем) │ ▼ - if domain && N≥1: tasks_create [-review] (blocked-by impl) - if service: review-umbrella — сервисная таска (blocked, blocker=impl#) - if skill: tasks_create [-review] (blocked-by impl, behavioral smoke-test) + review-umbrella: mcp__mappa__task_create (blocked, blocker=impl#) │ ▼ - covering-письмо в инбокс цели (оба канала; канон mappa-delegation) + covering-письмо: mcp__mappa__inbox_send (канон mappa-delegation) │ ▼ - Write .wiki/concepts/.md ← ВСЕГДА, любой маршрут - (summary: решения, куда промочено, задачи, ссылки) - │ - ▼ - git -C ~/projects/.workshop mv .brainstorm/.md .archive/-.md - │ - ▼ - append to .wiki/log.md + финальный отчёт (wiki:NNNN — спека, storm:N — архив, таски) ``` ## Steps -1. **Прочитать `.brainstorm/.md`.** Показать summary (≤2 абзаца). +1. **Найти шторм в mappa.** `mcp__mappa__entity_search(type='storm', + project=<проект>, q=)` → в результатах storm:N + **internal id**. + Прочитать полный буфер: `mcp__mappa__entity_get(id=)` — тело = + running record шторма (frontmatter + раунды). -2. **Спросить тип:** - - **workshop-meta** — методология самой workshop-зоны: ретро дистилляции, паттерны, апгрейды скилов зоны. + - Если шторм не найден, но пользователь показывает файловый + `.workshop/.brainstorm/.md` — это легаси: он уже импортирован или + доимпортируется в mappa storm-сущность (оператор, 2026-08-25). Скил + работает с storm-сущностью; файлы не трогает. + - Если шторма нет ни в mappa, ни в файлах — создать storm-сущность: + HTTP `POST /entities` с `x-api-token: $MAPPA_API_TOKEN`, + body `{project, type:'storm', slug, status:'buffer', body}` (MCP-тула + `storm.create` пока нет — follow-up на mappa; контракт POST /entities, + решение 7/#1054). + +2. **Показать summary буфера (≤2 абзаца).** + +3. **Спросить тип:** + - **workshop-meta** — методология самой workshop-зоны: ретро дистилляции, + паттерны, апгрейды скилов зоны. - **domain** — доменное содержимое для какого-то целевого проекта. - - **skill** — методология общего назначения, оформляется как скил в `~/projects/claude-skills/`. + - **skill** — методология общего назначения, оформляется как скил в + `~/projects/skills/`. -3. **Если domain:** - - Спросить целевой проект (имя папки в `~/projects/`). - - Валидация: вызвать `mcp__projects-meta__meta_status`, убедиться что проект известен; иначе — abort с сообщением «зарегистрируй проект через setup-projects-meta». - - **Определить канал борда:** есть ли у проекта файловая доска `.tasks/STATUS.md` (file channel) или борд живёт в mappa-сущностях (service channel — сервисные проекты: mappa, .common, …). Проверка: файл `.tasks/STATUS.md` в чек-ауте (file) против `mcp__mappa__task_list(project=)` / `entity_search` (service). Если файловой доски нет, а mappa-сущности есть → **service channel**. - -4. **Если domain + service channel (mappa-борд, fold-in 1):** - - **Create — карв-аут, лиз НЕ нужен** (wiki:2660): `task_create`/`wiki_create` - без claim_token (интерактивный контракт, поллер вне mappa). - - **Спека → вики-сущность:** `mcp__mappa__wiki_create(project, slug, body)` (или `wiki_update(project, id, version, …)`, если страница уже есть). Если спека уже в вики проекта (wiki:NNNN) — не дублировать, описание импл-тасок ссылается на неё. **Frontmatter-summary (wiki:2661):** при создании пиши `summary:` одной строкой в frontmatter — карточки `wiki.search` и поиск по вики читают его. - - **Pointers-таска НЕ нужна**, если спека уже в вики проекта — дыра pointers закрыта инлайн (описание импл-тасок прямо ссылается на спеку). - - **Импл-таски:** `mcp__mappa__task_create(project, slug, title, description, status='ready')` — **ПОСЛЕДОВАТЕЛЬНО, не батчем** (см. NB в шаге 7). - - **Review-umbrella:** сервисная таска `mcp__mappa__task_create(status='blocked', blocker=<номера импл-тасок>)`. - - **Covering-письмо:** `mcp__mappa__inbox_send(project=, from=<своя>, subject='Промоушен : таски <#N>…', body=<перечень>).` — канон mappa-delegation: таска на борде не пингует живую сессию. +4. **Если domain:** спросить целевой проект (имя папки в `~/projects/`). + Проверить, что проект существует в mappa: `mcp__mappa__entity_search` + type=project или `admin_status` (список проектов). Если нет — abort с + сообщением. 5. **Если skill:** - - Спросить `` нового скила (если не указан) — валидный slug (`[a-z0-9-]+`). - - Валидация: `~/projects/claude-skills/skills//` НЕ должна существовать. Если существует — **abort** с сообщением «скил `` уже существует, обновляйся обычным маршрутом в `claude-skills/`, этот скил не для апдейтов». - - Валидация: `~/projects/claude-skills/` сам репозиторий существует. Если нет — abort с сообщением «клонируй claude-skills/ через update-claude-skills или вручную». + - Спросить `` нового скила (если не указан) — валидный slug + (`[a-z0-9-]+`). + - Валидация: `~/projects/skills/skills//` НЕ должна существовать. + Если существует — **abort** с сообщением «скил `` уже существует, + обновляйся обычным маршрутом в `~/projects/skills/`, этот скил не для + апдейтов». + - Валидация: `~/projects/skills/` сам репозиторий существует. Если нет — + abort с сообщением «клонируй skills через update-skills или вручную». -6. **Парсинг action-items:** - - regex по строкам вида `- [ ] ...`, `- [ ]`, секции после `## Следующие шаги`/`## TODO`/`## Next steps`/`## Action items`. - - Показать список, дать редактировать/удалять/добавлять. - - Если 0 action-items — продолжить, не блокировать. +6. **Промоут контента (всегда через `storm_promote`, решение 7):** -7. **Промоушен контента:** + `mcp__mappa__storm_promote(project=, storm_id=)` - - **workshop-meta:** `Write` → `.wiki/concepts/.md` с frontmatter: + - Атомарно: buffer → wiki-страница (slug из шторма, body сохраняется, + рёбра parent_of wiki→storm и refs→storm) + шторм → `archive` + + значимое событие `storm.promoted`. + - **workshop-meta:** `project='.workshop'` → спека/концепт в вики зоны. + - **domain:** `project=` → спека в вики целевого проекта. **Frontmatter-summary + (wiki:2661):** убедиться, что в теле шторма есть `summary:` одной строкой + в frontmatter — карточки `wiki.search` читают его. Если нет — дописать + перед промоутом (через HTTP PATCH body шторма, entities.update). + - **skill:** контент шторма НЕ промоутится в вики (каркас пустой, тело + дописывается вторым проходом глазами) — но шторм всё равно архивируется + `storm_promote(project=<где шторм>)`, чтобы буфер не висел. + - Повторный промоут архивированного шторма → ошибка (one-shot, идемпотентно + через статус). Сверить `storm_id` (internal) из шага 1. + - Если `storm_promote` упал (конфликт версии, 409) → retry со свежим + internal id; при стабильном отказе — abort до создания тасок. - ```yaml - --- - date: - source: .brainstorm/.md - status: promoted - type: workshop-meta - --- - ``` - - Тело — содержимое буфера (можно слегка причесать заголовки, секции типа TODO убрать — они уже сепарированы в action-items). - - - **domain:** `mcp__projects-meta__knowledge_ingest` с параметрами: - - `project: ` - - `path: concepts/.md` (внутри target wiki) - - `content: <тело буфера с frontmatter>` - - Если `knowledge_ingest` падает → abort до tasks_create и до `git mv`. Сообщить пользователю. - - - **skill:** двухпроходной. - - **Проход первый (этот скил):** - - 1. **Диалог по `description`** — поведенческий контракт активации скила. Показать пользователю summary буфера и спросить: - - На каких триггер-фразах скил должен активироваться? (минимум 2-3, лучше — пары русский/английский) - - Что скил делает в одном предложении? - - Когда скил **не должен** активироваться (антипаттерны)? - - Из ответов собрать `description` строкой ~200-400 символов в стиле существующих скилов (см. `~/projects/claude-skills/skills/*/SKILL.md` для примеров). - - 2. **Preview + confirm** (обязательно): - ``` - Писать в: ~/projects/claude-skills/skills//SKILL.md - Frontmatter: name=, version=0.1.0, description=<...> - Body: пустой каркас с заголовками - When to use / Inputs / Steps / Failure modes / Side effects / What NOT to do - Коммит: feat(skills): add v0.1.0 (promoted from .workshop/.brainstorm/.md) - Без: install.sh, push, build-hermes (это в созданных тасках) - ОК? - ``` - - 3. После confirm: - - `mkdir -p ~/projects/claude-skills/skills//` - - `Write` файла `~/projects/claude-skills/skills//SKILL.md`: - - ```markdown - --- - name: - version: 0.1.0 - description: <вписанный пользователем триггер-контракт> - --- - - # - - <одно-два предложения что скил делает — из диалога> - - ## When to use - - <пусто, дописывается во втором проходе> - - ## Inputs - - <пусто> - - ## Steps - - <пусто> - - ## Failure modes - - <пусто> - - ## Side effects - - <пусто> - - ## What NOT to do - - <пусто> - ``` - - - В `~/projects/claude-skills/`: `git -C ~/projects/claude-skills add skills//SKILL.md && git -C ~/projects/claude-skills commit -m "feat(skills): add v0.1.0 (promoted from ~/projects/.workshop/.brainstorm/.md)"`. - - **STOP.** Не запускать `install.sh`. Не делать `git push`. Не править `hermes/mapping.yaml`. Это всё уйдёт тасками на шаге 7. - - **Проход второй** — пользователь явно зовёт «доведём ``» в этой же или следующей сессии. Источник лежит в `.archive/-.md`, тело каркаса дописывается глазами. Вне scope этого скила. +7. **Парсинг action-items:** regex по строкам вида `- [ ] ...` в теле шторма, + секции после `## Следующие шаги`/`## TODO`/`## Next steps`/ + `## Action items`. Показать список, дать редактировать/удалять/добавлять. + Если 0 action-items — продолжить, не блокировать. 8. **Создание тасок:** - > **NB (2026-08-24, инцидент mappa-skill-suite):** таски создавать **ПОСЛЕДОВАТЕЛЬНО**, не батчем и не параллельно. Параллельный `tasks_create` → гонка на sha-CAS общего счётчика (agenda-репо): часть тасок падает с PushRejected (при промоуте mappa-skill-suite 6/7 упали, повторены последовательно). Один `tasks_create` → дождаться ответа → следующий. + > **NB:** таски создавать **ПОСЛЕДОВАТЕЛЬНО**, не батчем. Один + > `task_create` → дождаться ответа → следующий. - - **domain (mandatory pre-impl) — `[-pointers]`:** **первой** создать таску, заполняющую `.wiki/CLAUDE.md` Domain conventions у target-проекта пойнтерами на спецификацию. Без неё импл-таски будут подняты со stub'ом в Domain conventions, и следующий агент попадёт в дыру: dense `where_stopped` one-liner + пустой stub = угадывание порогов / таксономий / pipeline-этапов. Параметры: + - **workshop-meta / domain:** для каждого action-item — + `mcp__mappa__task_create(project=, slug=, title, description, + status='ready')`. Create — карв-аут, лиз не нужен (wiki:2660/#1054). + Описание импл-таски ссылается на спеку (wiki:NNNN из шага 6). + - **skill:** три baseline-таски в `project='skills'`: + - `[-install]` — запустить `install.sh` в `~/projects/skills/`, + проверить активацию в новой сессии. + - `[-hermes-mapping]` — запись в `~/projects/skills/hermes/mapping.yaml` + (режим `auto` для стилевых, `pending` если трогает тулы/окружение). + - `[-test-trigger]` — прогнать триггер-фразы из description: + активируется на своих, не активируется на 2-3 близких чужих. + Плюс content-таски из буфера (если были) — тоже в `project='skills'`, + slug-prefix `-`. + - Если N-я таска упала — продолжить остальные, в конце сообщить какие + созданы / какие нет. Запомнить slug'и для review-umbrella. - - `target_project: ` - - `slug: -pointers` - - `status: ready` - - `description:` шаблон ниже - - `next_action:` готовый блок текста для копирования в `.wiki/CLAUDE.md` (шаблон ниже) +9. **Review-umbrella (для domain с импл-тасками и для skill — всегда):** - Description-шаблон: + `mcp__mappa__task_create(project=, slug=-review, + status='blocked', blocker=<номера импл-тасок через запятую>, description=<чек-лист>)` - ``` - Bootstrap-pointers для design . Pre-fills target's `.wiki/CLAUDE.md` - Domain conventions ссылками на спецификацию. Дизайн не лежит в этом репо — - только pointer-stub. Без этой таски следующий агент попадёт в дыру: - where_stopped one-liner + пустой Domain conventions stub = угадывание - порогов / таксономий / pipeline-этапов вместо чтения готовых решений. + - **Кто делает:** не имплементер. Следующая сессия в этом проекте (другая + модель / другой день / другой агент) с чистым контекстом. «Я только что + это написал» bias = главный риск. + - Чек-лист: прочитать спеку (wiki:NNNN из шага 6), `git log` shipped-коммитов, + для каждой импл-таски прогнать тесты и сверить с acceptance criteria, + findings → follow-up tasks через `task_create`. + - Закрытие: все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» + в close-note. + - Если review-таска упала — сообщить, **продолжить** к шагу 10 (промоут уже + сделан, шторм в archive). - **Кто делает:** любой следующий агент в этом проекте. Это первая по - приоритету таска промоушена — все остальные импл-таски ссылаются на - pointers через .wiki/CLAUDE.md. - ``` +10. **Covering-письмо в инбокс цели (канон mappa-delegation).** Таска на борде + не пингует живую сессию, письмо = пинг + контекст: - Next-action шаблон (pre-filled, копировать дословно — подменив `` и ``): + `mcp__mappa__inbox_send(project=, from=<своя папка>, subject='Промоушен + : таски <#N…>', body=<перечень + wiki:NNNN спека>)` - ``` - В `.wiki/CLAUDE.md` секции "Domain conventions" вставить блок (или заменить - дефолтный setup-wiki stub): - - ### Mandatory: read design context before implementation - - Before picking up any task in `.tasks/`, load the full design context. It - does **not** live in this repo — only pointers do. Sources, in order: - - 1. **Global wiki design (canonical):** `mcp__projects-meta__knowledge_get` - с `slug = "concepts/"`. Architecture decisions, contracts, scope. - 2. **Brainstorm process trace (rationale):** - `~/projects/.workshop/.archive/-.md`. - Why each decision was made, what was rejected and why, anti-patterns. - 3. **Local `overview.md`** — thin summary of (1), used as quick orientation - only — never as the source of truth. - - Do **not** invent thresholds, taxonomies, container topology, or pipeline - stages from task `where_stopped` lines alone — those are pointers, not - specifications. - - --- - - Закоммитить: `wiki(claude): add design-context pointers for `. - ``` - - Конкретные значения, которые промоутер должен подставить **заранее** в - текст next_action перед `tasks_create`: - - - `` — тема промоушена (тот же slug, что используется в `concepts/.md` и в `.archive/-.md`). - - `` — сегодняшняя дата (та же, что в шаге 9 архивации). - - Если `tasks_create` для `-pointers` упала → **abort** до content-тасок и до review. Без pointers оставшиеся таски бесполезны: импл-агент будет угадывать. Сообщить пользователю, буфер оставить на месте. - - - **workshop-meta / domain (content):** для каждого action-item: - - `mcp__projects-meta__tasks_create` с `project: ` (для domain) или с `project: ` (для workshop-meta — спросить пользователя если неоднозначно). - - Title — первая строка action-item; description — остальное. - - - **skill:** **всегда** добавляются три baseline-таски в `project: claude-skills`: - - `[-install]` — запустить `install.sh` в `~/projects/claude-skills/`, проверить что скил активируется в новой сессии, сделать `/reload-plugins`. - - `[-hermes-mapping]` — добавить запись в `~/projects/claude-skills/hermes/mapping.yaml`. Режим: `auto` если скил чисто стилевой / response-style, `pending` если скил трогает инструменты или окружение (требует отдельного аудита). - - `[-test-trigger]` — прогнать триггер-фразы из `description` на тестовом буфере: убедиться что активируется на своих фразах И не активируется на 2-3 близких чужих (false-positive check). - - Плюс content-таски из самого буфера (если были) — также в `project: claude-skills`, slug-prefix `-`. - - - Если N-я таска упала — продолжить остальные, в конце сообщить какие созданы / какие нет. - - Запомнить slug'и созданных импл-тасок для шага 9. - -9. **Review-чекпоинт.** Создаётся всегда для skill-промоушена; для domain-промоушена — только если N≥1 импл-тасок; для workshop-meta или N=0 (domain) — skip с пометкой в логе. - - - **domain (N≥1):** - - `mcp__projects-meta__tasks_create`: - - `target_project: ` - - `slug: -review` - - `status: blocked` - - `blocker:` `«bootstrap: -pointers; impl-tasks: <номера #n через запятую>»` — блокеры по номерам (номер = машинный ключ; слаги оставить в скобках для читаемости). - - `description:` шаблон ниже. - - `next_action:` «Дождаться 🟢 у всех blocker-тасок (включая `-pointers` — без него pointers в `.wiki/CLAUDE.md` не залиты, и review будет читать stub). Прочитать спецификацию (см. путь в description). Для каждой импл-таски: `git show `, прогнать тесты в её scope'е, сверить с acceptance criteria. Findings → новые follow-up tasks через `mcp__projects-meta__tasks_create`.» - - Description-шаблон (domain): - - ``` - Code-review checkpoint для брейнсторма (промоушен ). - - **Спецификация:** <путь к промоушенному design-документу — concepts/.md в target-wiki>. - **Pre-impl bootstrap:** `-pointers` (заполнил `.wiki/CLAUDE.md` Domain conventions — без него review бы читал stub). - **Импл-таски (review против их acceptance criteria):** <номера #n из шага 9, слаги в скобках>. - - **Кто делает:** **не имплементер.** Следующая сессия в этом проекте (другая модель / другой день / другой агент) поднимает таску с чистым контекстом. «Я только что это написал» bias = главный риск. - - **Чек-лист ревью:** - - Прочитать спецификацию (acceptance criteria каждой импл-таски). - - `git log --oneline` shipped-коммитов (по slug или scope в commit-message). - - Для каждой импл-таски: прогнать соответствующие тесты, реально проверить что они доходят до своих веток (не coverage-illusion). - - Сверить дизайн-decisions со shipped-кодом (signature, params, error-paths, безопасность). - - Findings — отдельные follow-up tasks (`--fix` или подобное) через `tasks_create`. - - **Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note. - ``` - - - **skill:** - - `mcp__projects-meta__tasks_create`: - - `target_project: claude-skills` - - `slug: -review` - - `status: blocked` - - `blocker:` `«impl-tasks: -install, -hermes-mapping, -test-trigger[, content-impls если были]»` — номера `#n` из шага 9 (слаги в скобках для читаемости). - - `description:` шаблон ниже. - - `next_action:` «Дождаться 🟢 у baseline-тасок. Прогнать поведенческий smoke-test (см. чек-лист в description). Findings → follow-up tasks через `tasks_create`.» - - Description-шаблон (skill): - - ``` - Skill-review checkpoint для (промоушен ). - - **Источник дизайна:** .workshop/.archive/-.md. - **Импл-таски:** -install, -hermes-mapping, -test-trigger[, content-impls] — номера #n из шага 9. - - **Кто делает:** **не имплементер.** Другая сессия / другой день / другой агент. Identity-not-location: ревьюер работает в любой папке, где есть доступ к файлам (см. `.workshop/.wiki/concepts/workshop-architecture.md` §5.1). - - **Поведенческий smoke-test (это и есть acceptance):** - - Скил активируется в чистой сессии на каждой триггер-фразе из `description` (русский И английский варианты). - - Скил **не** активируется на 2-3 близких но не своих фразах из соседних доменов (false-positive check). - - Каждый шаг секции `Steps` отрабатывает на тестовом буфере без ошибок. - - `Failure modes` уводят в abort, не в частичный успех с грязным состоянием. - - `What NOT to do` соответствует реальности — нет дыры между правилом и реализацией. - - Findings — обычные follow-up tasks (`--fix` или подобное) через `tasks_create` в `claude-skills`. - - **Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note. - - **NB по семверу:** `version: 0.1.0` записан промоутером. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила и не ревьюера. Если ревью требует правок — правит владелец, бампит он же. - ``` - - - Если `tasks_create` review-таски упала — сообщить пользователю, **продолжить** к шагу 11 (архивация буфера). Review-таску можно создать вручную позже из `.archive/-.md`. - - - **domain (service channel):** review-umbrella — **сервисная таска**: `mcp__mappa__task_create(project=, slug=-review, status='blocked', blocker=<номера импл-тасок через запятую>, description=<шаблон domain выше, спека = wiki:NNNN в вики проекта>)` — create = карв-аут (без лиза). Pointers-таска отсутствует (спека в вики). - - **Covering-письмо в инбокс цели (оба канала; канон mappa-delegation).** После создания тасок — `inbox_send` получателю-проекту: таска на борде не пингует живую сессию, письмо = пинг + контекст. File channel: `mcp__mappa__inbox_send(project=, from=<своя>, subject='[event: created] тасок', body=<перечень: #N slug> )`. Service channel: то же, но `from` = своя папка (или сервисный адрес) и тело ссылается на wiki:NNNN-спеку. - -10. **Workshop-wiki summary (обязательно для всех маршрутов):** - - `Write` → `.wiki/concepts/.md` с frontmatter: - - ```yaml - --- - date: - source: .brainstorm/.md → .archive/-.md - status: promoted - type: workshop-meta - --- - ``` - - Содержание (≤60 строк): - - **Что решили** — ключевые решения раундов (не пересказ, а outcomes). - - **Куда промочено** — полный путь: target-wiki / claude-skills / local concepts. - - **Задачи** — перечень slug'ов, созданных в шаге 7. - - **Ссылки** — архив буфера + связанные концепты в workshop-вики + глобальная вики. - - Для **workshop-meta**: summary — сокращение полного контента (который уже в `.wiki/concepts/.md` шага 6); если шаг 6 уже записал туда полный файл — шаг 9 его дополняет секцией «Куда промочено / Задачи» или пропускается (не дублировать). - - Затем обновить `index.md` — добавить строку в нужную секцию. - - Если `Write` упал → сообщить, **не блокировать** архивацию (summary менее критична чем content-промоушен). - -11. **Архивация:** - - ```bash - git -C ~/projects/.workshop mv .brainstorm/.md .archive/-.md - ``` - - **Только** если шаги 6 и 7 прошли (или прошли с допустимым partial — пользователь подтвердил). Иначе — оставить буфер на месте, чтобы можно было ретраиить. - -12. **Лог:** дописать в `.wiki/log.md`: - - ``` - promoted [created N tasks in ] - ``` - - Для skill — `` = `claude-skills/skills//SKILL.md (skeleton)`. - -13. **Финальный отчёт пользователю:** - - Куда промочено (полный путь). - - Какие таски созданы (id, title, проект). - - Куда уехал исходник. - - **Для skill:** напомнить что нужен второй проход «доведём ``» для дописывания тела каркаса. +11. **Финальный отчёт пользователю:** + - Куда промочено: `wiki:NNNN` (спека в вики target). + - Архив: `storm:N` (status=archive, номер стабилен). + - Какие таски созданы (ref, title, проект). + - **Для skill:** напомнить про второй проход «доведём ``». ## Failure modes -- `.brainstorm/.md` отсутствует → abort. -- `mcp__projects-meta` недоступен → abort до записей. -- Целевой проект (для domain) не найден в `meta_status` → abort. -- `knowledge_ingest` упал → abort до `tasks_create` и `git mv`. Буфер остаётся. -- **Service channel:** create упал (гонка счётчика/переходный период) → **повторить последовательно**, не батчем; при стабильном отказе — abort до архивации. -- **Service channel:** спека уже существует в вики проекта (wiki:NNNN) → не дублировать `wiki_create`, ссылаться на неё. -- **domain:** `tasks_create` для `[-pointers]` упал → **abort** до content-тасок и до review-таски. Без pointers оставшиеся таски бесполезны (агент будет угадывать). Сообщить пользователю; буфер оставить на месте для retry. -- `tasks_create` упал на N-й content-таске → продолжить остальные. Сообщить partial. **Не делать** `git mv` без подтверждения пользователя. -- `tasks_create` упал на review-таске (шаг 8) → не блокировать; перейти к архивации, сообщить пользователю чтобы создал вручную из `.archive/`. -- **Skill:** `~/projects/claude-skills/` не существует → abort с сообщением «клонируй через update-claude-skills или вручную». -- **Skill:** `~/projects/claude-skills/skills//` уже существует → abort с сообщением «скил уже существует, обновляйся обычным маршрутом в `claude-skills/`». -- **Skill:** пользователь не подтвердил preview перед записью → abort, состояние не меняется. -- **Skill:** локальный `git commit` в `claude-skills/` упал (например, не настроен user.email) → файл остаётся, сообщить пользователю что коммит нужно сделать руками; **не** делать `git mv` буфера до подтверждения. +- Шторм не найден в mappa (нет storm-сущности и нет файлового легаси) → abort, + сообщить: создать шторм через HTTP POST /entities (шаг 1) или дождаться + импорта. +- Целевой проект (domain) не существует в mappa → abort до промоута. +- `storm_promote` упал (409 версия / стабильный отказ) → retry со свежим + internal id; при повторном отказе — abort до создания тасок. Шторм остаётся + в buffer — ретраится позже. +- Шторм уже `archive` (повторный вызов) → abort: промоут one-shot, идемпотентность + через статус (решение 7). +- `task_create` упал на N-й content-таске → продолжить остальные, сообщить + partial. Промоут уже сделан — шторм не откатывается. +- `task_create` review-umbrella упал → не блокировать, сообщить пользователю + (создать вручную из шага 9). +- **Skill:** `~/projects/skills/` не существует → abort. +- **Skill:** `~/projects/skills/skills//` уже существует → abort. +- **Skill:** пользователь не подтвердил preview → abort, состояние не меняется. +- **Skill:** локальный `git commit` в `~/projects/skills/` упал → файл остаётся, + сообщить что коммит нужно сделать руками; промоут шторма не блокируется. ## Side effects -- **Всегда (любой маршрут):** создаёт summary-страницу `.wiki/concepts/.md` в `.workshop/` + добавляет строку в `index.md`. -- **workshop-meta:** summary IS контент (шаг 6 записывает полное тело; шаг 9 дополняет секцию «задачи/ссылки» или пропускается если уже полный). -- **domain:** создаёт запись в target-wiki через MCP (`mcp__projects-meta__knowledge_ingest`). -- **domain (service channel):** создаёт спека-сущность в вики mappa-проекта (`mcp__mappa__wiki_create`, карв-аут wiki:2660); импл-таски + review-umbrella — сервисные таски (`mcp__mappa__task_create`, карв-аут); covering-письмо в инбокс цели (`inbox_send`). Pointers-таска НЕ создаётся (спека уже в вики). -- **domain:** создаёт также **mandatory pre-impl** таску `[-pointers]` в target — pre-filled блок текста для `.wiki/CLAUDE.md` Domain conventions (ссылки на global wiki slug + workshop archive trace + local overview.md). Без неё последующий импл-агент попадает в дыру: where_stopped one-liner + пустой Domain conventions stub. -- **skill:** создаёт `~/projects/claude-skills/skills//SKILL.md` — **только шапка + пустой каркас**. Локальный коммит в `claude-skills/`. **Без** установки, push, или build-hermes — это всё в созданных baseline-тасках. -- Создаёт N тасок в target `.tasks/` через MCP. -- Для domain (N≥1) или skill: создаёт зонтичную review-таску (status=blocked, blocker=impl-slugs; для domain — также включает `-pointers`) в том же target. -- Перемещает `.brainstorm/.md` → `.archive/-.md`. -- Аппендит строку в `.wiki/log.md`. -- **Семвер скилов:** при target=skill промоутер записывает `version: 0.1.0` в шапку. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила. При попытке промоушена в существующий скил — abort (см. Failure modes). +- **Всегда:** `storm_promote` — атомарно wiki-страница в target + шторм → + `archive` + рёбра parent_of (wiki→storm, refs→storm) + событие `storm.promoted`. + Файловый `.archive/` НЕ трогается (легаси read-only). +- **workshop-meta:** wiki-страница (концепт) в вики `.workshop`. +- **domain:** спека-страница в вики целевого проекта (с frontmatter-summary, + wiki:2661) + импл-таски + review-umbrella + covering-письмо. +- **skill:** каркас `~/projects/skills/skills//SKILL.md` (только шапка + + пустой 6-секционный каркас) + локальный коммит в `~/projects/skills/`. + **Без** install.sh, push, build-hermes — это в baseline-тасках. +- Создаёт N тасок в target через `mcp__mappa__task_create` (карв-аут). +- Создаёт review-umbrella таску (status=blocked, blocker=impl#). +- Отправляет covering-письмо в инбокс target. ## What NOT to do -- Не писать доменное содержимое в локальный `.wiki/concepts/` (правило #1 из `.workshop/CLAUDE.md`). Summary-страница шага 11 — это trace/навигация, не domain-контент. -- Не пропускать шаг 9 (workshop-wiki summary) — именно так следующая сессия узнаёт что буфер был и куда ушёл. -- Не делать `git mv` буфера до успеха promotion+tasks. -- Не удалять буфер вместо `git mv` — теряется история. -- **Skill:** не пытаться автоматически переформатировать тело буфера в каркас `Steps`/`Failure modes`/etc. — это поведенческий контракт, не косметика. Каркас остаётся пустым; тело дописывается во втором проходе глазами. -- **Skill:** не запускать `install.sh`. Не делать `git push` в `claude-skills/`. Не править `hermes/mapping.yaml`. Не запускать `build-hermes.py`. Это работа baseline-тасок, не промоутера. -- **Skill:** не бампить `version` после первой записи (это работа владельца `claude-skills/`). -- **Skill:** не промоутить в существующий скил (см. Failure modes — abort). -- **Skill:** не пропускать обязательный preview + confirm перед `Write` — действие выходит за пределы мастерской, изменяет соседний репозиторий. -- **Service channel:** не батчить `task_create` (гонка sha-CAS счётчика, инцидент 2026-08-24: 6/7 упали) — только последовательно. Create — карв-аут, лиз не нужен. -- **Service channel:** не плодить pointers-таску, если спека уже в вики проекта (wiki:NNNN) — описание импл-тасок ссылается на неё инлайн. -- **Service channel:** не забывать covering-письмо в инбокс цели — таска на борде не пингует живую сессию. +- **Не писать в файловые `.brainstorm/`/`.archive/`** — read-only легаси после + флипа (решение 15). Буфер живёт в mappa storm-сущности. +- **Не использовать `mcp__projects-meta__tasks_create` / `knowledge_ingest` / + `knowledge_promote`** — файловые каналы выпилены. Таски — `mcp__mappa__task_create`, + вики — `storm_promote` (контент) + `wiki_create`/`wiki_update` (доп. страницы). +- Не делать `git mv` буфера в архив — промоут архивирует сам. +- Не удалять шторм вместо промоута — теряется граф-история (parent_of, refs). +- Не батчить `task_create` (гонка; инцидент 2026-08-24: 6/7 упали) — только + последовательно. +- Не забывать covering-письмо — таска на борде не пингует живую сессию. +- **Skill:** не переформатировать тело буфера в каркас автоматически — тело + дописывается вторым проходом глазами. +- **Skill:** не запускать `install.sh`, не делать push, не править + `hermes/mapping.yaml` — это baseline-таски. +- **Skill:** не промоутить в существующий скил (abort).