feat(skills): mappa-brainstorm-promote 1.6.0 — brainstorm-сущность, общий механизм mappa (без workshop-специфики и storm-сокращений) (#1066)
This commit is contained in:
BIN
dist/mappa-brainstorm-promote.skill
vendored
BIN
dist/mappa-brainstorm-promote.skill
vendored
Binary file not shown.
@@ -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-письмо — таска на борде не пингует живую сессию.
|
||||
|
||||
Reference in New Issue
Block a user