feat(skills): mappa-brainstorm-promote 1.6.0 — brainstorm-сущность, общий механизм mappa (без workshop-специфики и storm-сокращений) (#1066)

This commit is contained in:
2026-08-25 10:17:08 +03:00
parent aabf8da806
commit a1f12fcdd4
2 changed files with 115 additions and 152 deletions

Binary file not shown.

View File

@@ -3,45 +3,33 @@ name: mappa-brainstorm-promote
author: ours
version: 1.6.0
description: >
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 a matured brainstorm buffer (mappa entity type=brainstorm, status=buffer):
read buffer → choose target project → promote via mcp__mappa__brainstorm_promote
(atomic buffer → wiki-страница в target + archive, решение 7) → extract
action-items into target tasks (mcp__mappa__task_create, карв-аут) → review
umbrella → covering letter. Общий механизм mappa, как task.create/wiki.create —
никакой workshop-специфики. Старое имя — триггер-синоним:
workshop-promote-brainstorm. Triggers (user): «промоутни брейнсторм»,
«finalize <topic>», «выкати в вики», «promote <topic>».
---
# mappa-brainstorm-promote
Финализация созревшего шторм-буфера, который живёт **как mappa storm-сущность**
(type=storm, status=buffer) в любом проекте — **процедура** (линейная: от чтения
буфера до промоута и тасок), не цикл: запускается явно на финальном буфере и
доводит его до конца. В форкфлоу встаёт между работой (`mappa-task-work`) и
финишем (`mappa-closing-ritual`).
Финализация созревшего брейнсторм-буфера, который живёт **как mappa-сущность
типа `brainstorm`** (status=buffer). Это общий механизм mappa — ровно как
`task.create` или `wiki.create`: буфер существует в mappa, скил доводит его до
конца (промоут контента в вики + action-items тасками). Никакой
workshop-специфики: скил триггерится из любой папки, работает с brainstorm-
сущностями любого проекта.
> **Project-agnostic.** Шторм ведётся там, где его ведут, — не только в
> `.workshop/`. Скил триггерится из любой папки; буфер ищется в mappa
> (`entity_search` type=storm), а не на диске. Файловые `.brainstorm/`/
> `.archive/` — read-only легаси: их содержимое уже импортировано в mappa
> storm-сущности (решение 15, флип), новые записи в файлы не делаются.
Процедура линейная (от чтения буфера до промоута и тасок), не цикл: запускается
явно на финальном буфере и доводит его до конца. В форкфлоу встаёт между
работой (`mappa-task-work`) и финишем (`mappa-closing-ritual`).
Три ветки маршрутизации (спросить пользователя):
- **workshop-meta** → промоут в `.workshop`: wiki-страница в вики зоны
(методология самой зоны).
- **domain** → промоут в целевой проект: wiki-страница (спека) в его вики +
импл-таски + review-umbrella.
- **skill** → каркас скила в `~/projects/skills/skills/<name>/SKILL.md`
(только шапка + пустой каркас тела, локальный коммит без push/install).
Промоут контента — **всегда через `mcp__mappa__storm_promote`**: атомарно
создаёт wiki-страницу (slug из шторма, body сохраняется) в проекте из вызова и
переводит шторм в `archive` (номер/slug стабильны, решение 20; рёбра parent_of,
событие `storm.promoted`). **Никаких git mv и файловых архивов.** Action-items
**Промоут контента — всегда через `mcp__mappa__brainstorm_promote`:**
атомарно создаёт wiki-страницу (slug из буфера, body сохраняется) в проекте из
вызова и переводит буфер в `archive` (номер/slug стабильны, решение 20; рёбра
parent_of, событие `brainstorm.promoted`). Никаких файловых каналов. Action-items
уходят тасками в target-проект через `mcp__mappa__task_create` (карв-аут без
лиза, #1054; последовательно, не батчем).
@@ -49,49 +37,37 @@ description: >
- «промоутни брейнсторм», «finalize <topic>», «выкати в вики», «promote
<topic>».
- Пользователь ссылается на storm-сущность (storm:N) или на тему шторма,
которая созрела и готова к промоушену.
- Пользователь ссылается на brainstorm-сущность (brainstorm:N) или на тему
буфера, который созрел и готов к промоушену.
## Inputs
- Storm-реф `storm:N` или `<topic>` (slug/тема шторма) + project (если шторм
не в текущем проекте — спросить).
- Brainstorm-реф `brainstorm:N` или `<topic>` (slug/тема буфера) + project (если
буфер не в текущем проекте — спросить).
- Для skill-ветки дополнительно: `<name>` нового скила (если не указан —
спросить, предложить производное от topic).
## Decision flow
```
storm-сущность в mappa (type=storm, status=buffer)
brainstorm-сущность в mappa (type=brainstorm, status=buffer)
find + read (entity_search type=storm → entity_get полный body)
find + read (entity_search type=brainstorm → entity_get полный body)
ask: workshop-meta or domain or skill?
│ │
▼ ▼
│ ask: target proj ask: <name> + check
│ ~/projects/skills/
┌─────┴─────┐ skills/<name>/ NOT exists
▼ │
│ storm_promote storm_promote dialog: description (trigger contract)
│ (project=.workshop) (project=<target>) │
│ │ │ ▼
│ │ │ preview + confirm
│ │ │ │
│ │ │ ▼
│ │ │ mkdir + Write SKILL.md
│ │ │ (header + empty 6-section skeleton)
│ │ │ │
│ │ │ ▼
│ │ │ git add + commit in ~/projects/skills/
│ │ │ (local, no push, no install.sh)
│ │ │ │
└────────┴───────────┴────────────┘
ask: target project (куда промоутить)
├── обычный проект → brainstorm_promote(project=<target>)
│ → wiki-страница (спека) в вики target
└── skill → dialog: description (trigger contract)
→ preview + confirm
→ mkdir + Write SKILL.md (каркас) в ~/projects/skills/
→ git add + commit (local, no push/install)
parse action-items from storm body
parse action-items from buffer body
for each: mcp__mappa__task_create (ПОСЛЕДОВАТЕЛЬНО, не батчем)
@@ -103,41 +79,28 @@ storm-сущность в mappa (type=storm, status=buffer)
covering-письмо: mcp__mappa__inbox_send (канон mappa-delegation)
финальный отчёт (wiki:NNNN — спека, storm:N — архив, таски)
финальный отчёт (wiki:NNNN — спека, brainstorm:N — архив, таски)
```
## Steps
1. **Найти шторм в mappa.** `mcp__mappa__entity_search(type='storm',
project=<проект>, q=<topic>)` → в результатах storm:N + **internal id**.
1. **Найти буфер в mappa.** `mcp__mappa__entity_search(type='brainstorm',
project=<проект>, q=<topic>)` → в результатах brainstorm:N + **internal id**.
Прочитать полный буфер: `mcp__mappa__entity_get(id=<internal id>)` — тело =
running record шторма (frontmatter + раунды).
running record (frontmatter + раунды).
- Если шторм не найден, но пользователь показывает файловый
`.workshop/.brainstorm/<topic>.md` — это легаси: он уже импортирован или
доимпортируется в mappa storm-сущность (оператор, 2026-08-25). Скил
работает с storm-сущностью; файлы не трогает.
- Если шторма нет ни в mappa, ни в файлах — создать storm-сущность:
HTTP `POST <MAPPA_CORE_URL>/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).
Если буфера нет в mappa — создать brainstorm-сущность через
`mcp__mappa__brainstorm_create` (или HTTP `POST /entities` type=brainstorm,
контракт решения 7/#1054). Не изобретать файловые буферы.
2. **Показать summary буфера (≤2 абзаца).**
3. **Спросить тип:**
- **workshop-meta** — методология самой workshop-зоны: ретро дистилляции,
паттерны, апгрейды скилов зоны.
- **domain** — доменное содержимое для какого-то целевого проекта.
- **skill** — методология общего назначения, оформляется как скил в
`~/projects/skills/`.
3. **Спросить target-проект** — куда промоутить контент. По умолчанию — проект,
где буфер живёт (шторм ведут там, где тема релевантна). Проверить, что проект
существует в mappa: `mcp__mappa__entity_search` type=project или
`admin_status` (список проектов). Если нет — abort с сообщением.
4. **Если domain:** спросить целевой проект (имя папки в `~/projects/`).
Проверить, что проект существует в mappa: `mcp__mappa__entity_search`
type=project или `admin_status` (список проектов). Если нет — abort с
сообщением.
5. **Если skill:**
4. **Если target = skill (пользователь хочет оформить как скил):**
- Спросить `<name>` нового скила (если не указан) — валидный slug
(`[a-z0-9-]+`).
- Валидация: `~/projects/skills/skills/<name>/` НЕ должна существовать.
@@ -146,42 +109,43 @@ storm-сущность в mappa (type=storm, status=buffer)
апдейтов».
- Валидация: `~/projects/skills/` сам репозиторий существует. Если нет —
abort с сообщением «клонируй skills через update-skills или вручную».
- Двухпроходной каркас: диалог по `description` (триггер-контракт активации:
минимум 2-3 фразы, пары русский/английский; что делает; антипаттерны) →
preview + confirm → `Write` каркаса (шапка + 6 пустых секций) → локальный
`git commit` в `~/projects/skills/`. **Без** install.sh, push,
build-hermes — это в baseline-тасках шага 7. Тело каркаса дописывается
вторым проходом глазами (вне scope этого скила).
6. **Промоут контента (всегда через `storm_promote`, решение 7):**
5. **Промоут контента (всегда через `brainstorm_promote`, решение 7):**
`mcp__mappa__storm_promote(project=<target>, storm_id=<internal id>)`
`mcp__mappa__brainstorm_promote(project=<target>, brainstorm_id=<internal id>)`
- Атомарно: buffer → wiki-страница (slug из шторма, body сохраняется,
рёбра parent_of wiki→storm и refs→storm) + шторм → `archive` +
значимое событие `storm.promoted`.
- **workshop-meta:** `project='.workshop'` → спека/концепт в вики зоны.
- **domain:** `project=<target>` → спека в вики целевого проекта. **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 со свежим
- Атомарно: buffer → wiki-страница (slug из буфера, body сохраняется, рёбра
parent_of buffer→wiki и refs→buffer) + буфер → `archive` + значимое событие
`brainstorm.promoted`.
- **Frontmatter-summary (wiki:2661):** убедиться, что в теле буфера есть
`summary:` одной строкой в frontmatter — карточки `wiki.search` читают его.
Если нет — дописать перед промоутом.
- Повторный промоут архивированного буфера → ошибка (one-shot, идемпотентно
через статус). Сверить `brainstorm_id` (internal) из шага 1.
- Если `brainstorm_promote` упал (конфликт версии, 409) → retry со свежим
internal id; при стабильном отказе — abort до создания тасок.
7. **Парсинг action-items:** regex по строкам вида `- [ ] ...` в теле шторма,
6. **Парсинг action-items:** regex по строкам вида `- [ ] ...` в теле буфера,
секции после `## Следующие шаги`/`## TODO`/`## Next steps`/
`## Action items`. Показать список, дать редактировать/удалять/добавлять.
Если 0 action-items — продолжить, не блокировать.
8. **Создание тасок:**
7. **Создание тасок:**
> **NB:** таски создавать **ПОСЛЕДОВАТЕЛЬНО**, не батчем. Один
> `task_create` → дождаться ответа → следующий.
- **workshop-meta / domain:** для каждого action-item —
- **Обычный target:** для каждого action-item —
`mcp__mappa__task_create(project=<target>, slug=<kebab>, title, description,
status='ready')`. Create — карв-аут, лиз не нужен (wiki:2660/#1054).
Описание импл-таски ссылается на спеку (wiki:NNNN из шага 6).
- **skill:** три baseline-таски в `project='skills'`:
Описание импл-таски ссылается на спеку (wiki:NNNN из шага 5).
- **Skill:** три baseline-таски в `project='skills'`:
- `[<name>-install]` — запустить `install.sh` в `~/projects/skills/`,
проверить активацию в новой сессии.
- `[<name>-hermes-mapping]` — запись в `~/projects/skills/hermes/mapping.yaml`
@@ -193,7 +157,7 @@ storm-сущность в mappa (type=storm, status=buffer)
- Если N-я таска упала — продолжить остальные, в конце сообщить какие
созданы / какие нет. Запомнить slug'и для review-umbrella.
9. **Review-umbrella (для domain с импл-тасками и для skill — всегда):**
8. **Review-umbrella (для target с импл-тасками и для skill — всегда):**
`mcp__mappa__task_create(project=<target>, slug=<topic>-review,
status='blocked', blocker=<номера импл-тасок через запятую>, description=<чек-лист>)`
@@ -201,56 +165,54 @@ storm-сущность в mappa (type=storm, status=buffer)
- **Кто делает:** не имплементер. Следующая сессия в этом проекте (другая
модель / другой день / другой агент) с чистым контекстом. «Я только что
это написал» bias = главный риск.
- Чек-лист: прочитать спеку (wiki:NNNN из шага 6), `git log` shipped-коммитов,
- Чек-лист: прочитать спеку (wiki:NNNN из шага 5), `git log` shipped-коммитов,
для каждой импл-таски прогнать тесты и сверить с acceptance criteria,
findings → follow-up tasks через `task_create`.
- Закрытие: все findings зафайлены ИЛИ ревьюер подтвердил «нет findings»
в close-note.
- Если review-таска упала — сообщить, **продолжить** к шагу 10 (промоут уже
сделан, шторм в archive).
- Если review-таска упала — сообщить, **продолжить** к шагу 9 (промоут уже
сделан, буфер в archive).
10. **Covering-письмо в инбокс цели (канон mappa-delegation).** Таска на борде
9. **Covering-письмо в инбокс цели (канон mappa-delegation).** Таска на борде
не пингует живую сессию, письмо = пинг + контекст:
`mcp__mappa__inbox_send(project=<target>, from=<своя папка>, subject='Промоушен
<topic>: таски <#N…>', body=<перечень + wiki:NNNN спека>)`
11. **Финальный отчёт пользователю:**
10. **Финальный отчёт пользователю:**
- Куда промочено: `wiki:NNNN` (спека в вики target).
- Архив: `storm:N` (status=archive, номер стабилен).
- Архив: `brainstorm:N` (status=archive, номер стабилен).
- Какие таски созданы (ref, title, проект).
- **Для skill:** напомнить про второй проход «доведём `<name>`».
## Failure modes
- Шторм не найден в mappa (нет storm-сущности и нет файлового легаси) → abort,
сообщить: создать шторм через HTTP POST /entities (шаг 1) или дождаться
импорта.
- Целевой проект (domain) не существует в mappa → abort до промоута.
- `storm_promote` упал (409 версия / стабильный отказ) → retry со свежим
internal id; при повторном отказе — abort до создания тасок. Шторм остаётся
- Буфер не найден в mappa (нет brainstorm-сущности) → abort, сообщить: создать
через `brainstorm_create` (шаг 1) или HTTP POST /entities.
- Target-проект не существует в mappa → abort до промоута.
- `brainstorm_promote` упал (409 версия / стабильный отказ) → retry со свежим
internal id; при повторном отказе — abort до создания тасок. Буфер остаётся
в buffer — ретраится позже.
- Шторм уже `archive` (повторный вызов) → abort: промоут one-shot, идемпотентность
через статус (решение 7).
- Буфер уже `archive` (повторный вызов) → abort: промоут one-shot,
идемпотентность через статус (решение 7).
- `task_create` упал на N-й content-таске → продолжить остальные, сообщить
partial. Промоут уже сделан — шторм не откатывается.
partial. Промоут уже сделан — буфер не откатывается.
- `task_create` review-umbrella упал → не блокировать, сообщить пользователю
(создать вручную из шага 9).
(создать вручную из шага 8).
- **Skill:** `~/projects/skills/` не существует → abort.
- **Skill:** `~/projects/skills/skills/<name>/` уже существует → abort.
- **Skill:** пользователь не подтвердил preview → abort, состояние не меняется.
- **Skill:** локальный `git commit` в `~/projects/skills/` упал → файл остаётся,
сообщить что коммит нужно сделать руками; промоут шторма не блокируется.
сообщить что коммит нужно сделать руками; промоут буфера не блокируется.
## Side effects
- **Всегда:** `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/<name>/SKILL.md` (только шапка +
- **Всегда:** `brainstorm_promote` — атомарно wiki-страница в target + буфер
`archive` + рёбра parent_of (wiki→buffer, refs→buffer) + событие
`brainstorm.promoted`.
- **Обычный target:** спека-страница в вики целевого проекта (с
frontmatter-summary, wiki:2661) + импл-таски + review-umbrella + covering-письмо.
- **Skill:** каркас `~/projects/skills/skills/<name>/SKILL.md` (только шапка +
пустой 6-секционный каркас) + локальный коммит в `~/projects/skills/`.
**Без** install.sh, push, build-hermes — это в baseline-тасках.
- Создаёт N тасок в target через `mcp__mappa__task_create` (карв-аут).
@@ -259,13 +221,14 @@ storm-сущность в mappa (type=storm, status=buffer)
## What NOT to do
- **Не писать в файловые `.brainstorm/`/`.archive/`** — read-only легаси после
флипа (решение 15). Буфер живёт в mappa storm-сущности.
- **Не использовать файловые каналы** — буфер живёт в mappa brainstorm-сущности,
никаких `.brainstorm/`/`.archive/` записей.
- **Не использовать `mcp__projects-meta__tasks_create` / `knowledge_ingest` /
`knowledge_promote`** — файловые каналы выпилены. Таски — `mcp__mappa__task_create`,
вики — `storm_promote` (контент) + `wiki_create`/`wiki_update` (доп. страницы).
`knowledge_promote`** — файловые каналы выпилены. Таски —
`mcp__mappa__task_create`, вики — `brainstorm_promote` (контент) +
`wiki_create`/`wiki_update` (доп. страницы).
- Не делать `git mv` буфера в архив — промоут архивирует сам.
- Не удалять шторм вместо промоута — теряется граф-история (parent_of, refs).
- Не удалять буфер вместо промоута — теряется граф-история (parent_of, refs).
- Не батчить `task_create` (гонка; инцидент 2026-08-24: 6/7 упали) — только
последовательно.
- Не забывать covering-письмо — таска на борде не пингует живую сессию.