diff --git a/.tasks/2026-08-24-01060-mappa-brainstorm-promote.md b/.tasks/2026-08-24-01060-mappa-brainstorm-promote.md index 6000b37..b330f06 100644 --- a/.tasks/2026-08-24-01060-mappa-brainstorm-promote.md +++ b/.tasks/2026-08-24-01060-mappa-brainstorm-promote.md @@ -15,4 +15,14 @@ Fold-in 1: mappa-service target. Промоут в mappa-сервисные бо ## Completed steps +- [x] skills/mappa-brainstorm-promote/SKILL.md v1.2.0 (MINOR) — UPDATE workshop-promote-brainstorm: добавлена 4-я ветка маршрутизации **mappa-service** (fold-in 1: лиз через task_claim_next, спека через mcp__mappa__wiki_create, импл-таски через mcp__mappa__task_create, pointers-таска НЕ нужна если спека в вики w:NNNN, review-umbrella сервисная таска, covering-письмо в инбокс цели) +- [x] NB (2026-08-24, инцидент): tasks_create ПОСЛЕДОВАТЕЛЬНО, не батчем (гонка sha-CAS счётчика agenda; при промоуте mappa-skill-suite 6/7 упали) — в шаге 8 + failure modes + what-not-to-do +- [x] File channel (projects-meta → .tasks/STATUS.md) сохранён; шаги перенумерованы (вставлен шаг 4) +- [x] Старое имя workshop-promote-brainstorm — триггер-синоним в description; каталог git mv +- [x] lint clean (67 skills, 0 violations); build.sh → dist/mappa-brainstorm-promote.skill (старый .skill удалён); install.sh → dual; старый удалён из живых диров +- [x] GREEN micro-test: свежий pi -p на «промоутни брейнсторм… таргет mappa» → активация mappa-brainstorm-promote, service channel (лиз/task_create последовательно/wiki_create/без pointers/review-umbrella/covering-письмо) + ## Notes + +- RED-базис: UPDATE существующего скила (триггеры не менялись); дельта = fold-in 1 + NB последовательности. Полный behavioral smoke — за #1065. +- Актуальность шага 3 (определение канала): сервисные борды — mappa, .common (доска в mappa-сущностях); обычные проекты — файловая доска. Определение по наличию .tasks/STATUS.md. diff --git a/dist/mappa-brainstorm-promote.skill b/dist/mappa-brainstorm-promote.skill new file mode 100644 index 0000000..eeb6d1c Binary files /dev/null and b/dist/mappa-brainstorm-promote.skill differ diff --git a/dist/workshop-promote-brainstorm.skill b/dist/workshop-promote-brainstorm.skill deleted file mode 100644 index 42d5cab..0000000 Binary files a/dist/workshop-promote-brainstorm.skill and /dev/null differ diff --git a/skills/workshop-promote-brainstorm/SKILL.md b/skills/mappa-brainstorm-promote/SKILL.md similarity index 76% rename from skills/workshop-promote-brainstorm/SKILL.md rename to skills/mappa-brainstorm-promote/SKILL.md index d7cc3a3..75eab5c 100644 --- a/skills/workshop-promote-brainstorm/SKILL.md +++ b/skills/mappa-brainstorm-promote/SKILL.md @@ -1,21 +1,23 @@ --- -name: workshop-promote-brainstorm +name: mappa-brainstorm-promote author: ours -version: 1.1.0 +version: 1.2.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, skill → - claude-skills skeleton), extract action-items into target .tasks, create - pointers + review umbrella for impl tasks, archive the buffer. - Location-agnostic: fires from ANY folder; all paths resolve to - ~/projects/.workshop/ regardless of CWD. Triggers (user): «промоутни - брейнсторм», «finalize », «выкати в вики», «promote ». + .wiki/concepts/, domain → target project wiki via knowledge_ingest, + mappa-service → mappa-борд под лизом, 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 + ». --- -# workshop-promote-brainstorm +# mappa-brainstorm-promote -Финализирует созревший брейнсторм-буфер на столе босса (`~/projects/.workshop/`). Три ветки маршрутизации: +Финализирует созревший брейнсторм-буфер на столе босса (`~/projects/.workshop/`). Четыре ветки маршрутизации: > **Location-agnostic.** Скил триггерится из любой папки — босс-штормы > происходят где угодно, запись живёт на столе. Все относительные пути ниже @@ -25,6 +27,7 @@ description: > - **workshop-meta** → локальный `.wiki/concepts/` (методология самой зоны). - **domain** → глобал через `mcp__projects-meta__knowledge_ingest` в `~/projects//.wiki/`. +- **mappa-service** → сервисные борды (mappa, .common, …): таски/вики-сущности через `mcp__mappa__task_create`/`wiki_create` **под лизом** (`task_claim_next`); pointers-таска НЕ нужна, если спека уже в вики проекта (w:NNNN); review-umbrella — сервисная таска; covering-письмо в инбокс цели. - **skill** → `~/projects/claude-skills/skills//SKILL.md` (только шапка + пустой каркас тела, локальный коммит без push/install/build-hermes). Буфер уезжает в `.archive/`. Action-items уходят тасками в target-проект. **Всегда, при любом маршруте, в воркшоп-вики остаётся summary-страница.** @@ -53,35 +56,43 @@ description: > │ ▼ ▼ │ ask: target proj ask: + check │ │ ~/projects/claude-skills/ - │ ▼ skills// NOT exists - │ knowledge_ingest │ - │ │ ▼ - │ │ dialog: description (trigger contract) - │ │ │ - │ │ ▼ - │ │ preview + confirm - │ │ │ - │ │ ▼ - ▼ │ mkdir + Write SKILL.md -write to │ (header + empty 6-section skeleton) -.wiki/concepts │ │ - │ │ ▼ - │ │ git add + commit in claude-skills/ - │ │ (local, no push, no install.sh, no build-hermes) - │ │ │ - └──────────────┴──────────────┘ + │ ┌─────┴─────┐ skills// NOT exists + │ ▼ ▼ │ + │ file channel service channel │ + │ (.tasks/) (mappa-борд) │ + │ │ │ │ + │ ▼ ▼ ▼ + │ knowledge_ingest mcp__mappa__wiki_create dialog: description (trigger contract) + │ │ (под лизом) │ + │ │ │ ▼ + │ │ │ 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) + │ │ │ │ + └────────┴───────────┴─────────────────┘ │ ▼ parse action-items + (for skill: prepend 3 baselines) │ ▼ - for each: mcp__projects-meta__tasks_create + for each: tasks_create (ПОСЛЕДОВАТЕЛЬНО, не батчем) + [file: mcp__projects-meta__tasks_create | service: 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) │ ▼ + covering-письмо в инбокс цели (оба канала; канон mappa-delegation) + │ + ▼ Write .wiki/concepts/.md ← ВСЕГДА, любой маршрут (summary: решения, куда промочено, задачи, ссылки) │ @@ -104,18 +115,27 @@ write to │ (header + empty 6-section skeleton) 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. **Если skill:** +4. **Если domain + service channel (mappa-борд, fold-in 1):** + - **Лиз:** `mcp__mappa__task_claim_next(project=, owner=<своя>)` → `token`. + - **Спека → вики-сущность:** `mcp__mappa__wiki_create(project, slug, body, claim_token)` (или `wiki_update`, если страница уже есть). Если спека уже в вики проекта (w:NNNN) — не дублировать, описание импл-тасок ссылается на неё. + - **Pointers-таска НЕ нужна**, если спека уже в вики проекта — дыра pointers закрыта инлайн (описание импл-тасок прямо ссылается на спеку). + - **Импл-таски:** `mcp__mappa__task_create(project, slug, title, description, status='ready', claim_token)` — **ПОСЛЕДОВАТЕЛЬНО, не батчем** (см. NB в шаге 7). + - **Review-umbrella:** сервисная таска `mcp__mappa__task_create(status='blocked', blocker=<номера импл-тасок>)`. + - **Covering-письмо:** `mcp__mappa__inbox_send(project=, from=<своя>, subject='Промоушен : таски <#N>…', body=<перечень>).` — канон mappa-delegation: таска на борде не пингует живую сессию. + +5. **Если skill:** - Спросить `` нового скила (если не указан) — валидный slug (`[a-z0-9-]+`). - Валидация: `~/projects/claude-skills/skills//` НЕ должна существовать. Если существует — **abort** с сообщением «скил `` уже существует, обновляйся обычным маршрутом в `claude-skills/`, этот скил не для апдейтов». - Валидация: `~/projects/claude-skills/` сам репозиторий существует. Если нет — abort с сообщением «клонируй claude-skills/ через update-claude-skills или вручную». -5. **Парсинг action-items:** +6. **Парсинг action-items:** - regex по строкам вида `- [ ] ...`, `- [ ]`, секции после `## Следующие шаги`/`## TODO`/`## Next steps`/`## Action items`. - Показать список, дать редактировать/удалять/добавлять. - Если 0 action-items — продолжить, не блокировать. -6. **Промоушен контента:** +7. **Промоушен контента:** - **workshop-meta:** `Write` → `.wiki/concepts/.md` с frontmatter: @@ -204,7 +224,9 @@ write to │ (header + empty 6-section skeleton) **Проход второй** — пользователь явно зовёт «доведём ``» в этой же или следующей сессии. Источник лежит в `.archive/-.md`, тело каркаса дописывается глазами. Вне scope этого скила. -7. **Создание тасок:** +8. **Создание тасок:** + + > **NB (2026-08-24, инцидент mappa-skill-suite):** таски создавать **ПОСЛЕДОВАТЕЛЬНО**, не батчем и не параллельно. Параллельный `tasks_create` → гонка на sha-CAS общего счётчика (agenda-репо): часть тасок падает с PushRejected (при промоуте mappa-skill-suite 6/7 упали, повторены последовательно). Один `tasks_create` → дождаться ответа → следующий. - **domain (mandatory pre-impl) — `[-pointers]`:** **первой** создать таску, заполняющую `.wiki/CLAUDE.md` Domain conventions у target-проекта пойнтерами на спецификацию. Без неё импл-таски будут подняты со stub'ом в Domain conventions, и следующий агент попадёт в дыру: dense `where_stopped` one-liner + пустой stub = угадывание порогов / таксономий / pipeline-этапов. Параметры: @@ -276,9 +298,9 @@ write to │ (header + empty 6-section skeleton) Плюс content-таски из самого буфера (если были) — также в `project: claude-skills`, slug-prefix `-`. - Если N-я таска упала — продолжить остальные, в конце сообщить какие созданы / какие нет. - - Запомнить slug'и созданных импл-тасок для шага 8. + - Запомнить slug'и созданных импл-тасок для шага 9. -8. **Review-чекпоинт.** Создаётся всегда для skill-промоушена; для domain-промоушена — только если N≥1 импл-тасок; для workshop-meta или N=0 (domain) — skip с пометкой в логе. +9. **Review-чекпоинт.** Создаётся всегда для skill-промоушена; для domain-промоушена — только если N≥1 импл-тасок; для workshop-meta или N=0 (domain) — skip с пометкой в логе. - **domain (N≥1):** - `mcp__projects-meta__tasks_create`: @@ -296,7 +318,7 @@ write to │ (header + empty 6-section skeleton) **Спецификация:** <путь к промоушенному design-документу — concepts/.md в target-wiki>. **Pre-impl bootstrap:** `-pointers` (заполнил `.wiki/CLAUDE.md` Domain conventions — без него review бы читал stub). - **Импл-таски (review против их acceptance criteria):** <номера #n из шага 7, слаги в скобках>. + **Импл-таски (review против их acceptance criteria):** <номера #n из шага 9, слаги в скобках>. **Кто делает:** **не имплементер.** Следующая сессия в этом проекте (другая модель / другой день / другой агент) поднимает таску с чистым контекстом. «Я только что это написал» bias = главный риск. @@ -315,7 +337,7 @@ write to │ (header + empty 6-section skeleton) - `target_project: claude-skills` - `slug: -review` - `status: blocked` - - `blocker:` `«impl-tasks: -install, -hermes-mapping, -test-trigger[, content-impls если были]»` — номера `#n` из шага 7 (слаги в скобках для читаемости). + - `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`.» @@ -325,7 +347,7 @@ write to │ (header + empty 6-section skeleton) Skill-review checkpoint для (промоушен ). **Источник дизайна:** .workshop/.archive/-.md. - **Импл-таски:** -install, -hermes-mapping, -test-trigger[, content-impls] — номера #n из шага 7. + **Импл-таски:** -install, -hermes-mapping, -test-trigger[, content-impls] — номера #n из шага 9. **Кто делает:** **не имплементер.** Другая сессия / другой день / другой агент. Identity-not-location: ревьюер работает в любой папке, где есть доступ к файлам (см. `.workshop/.wiki/concepts/workshop-architecture.md` §5.1). @@ -343,9 +365,13 @@ write to │ (header + empty 6-section skeleton) **NB по семверу:** `version: 0.1.0` записан промоутером. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила и не ревьюера. Если ревью требует правок — правит владелец, бампит он же. ``` - - Если `tasks_create` review-таски упала — сообщить пользователю, **продолжить** к шагу 9 (архивация буфера). Review-таску можно создать вручную позже из `.archive/-.md`. + - Если `tasks_create` review-таски упала — сообщить пользователю, **продолжить** к шагу 11 (архивация буфера). Review-таску можно создать вручную позже из `.archive/-.md`. -9. **Workshop-wiki summary (обязательно для всех маршрутов):** + - **domain (service channel):** review-umbrella — **сервисная таска**: `mcp__mappa__task_create(project=, slug=-review, status='blocked', blocker=<номера импл-тасок через запятую>, description=<шаблон domain выше, спека = w:NNNN в вики проекта>, claim_token)` под тем же лизом. Pointers-таска отсутствует (спека в вики). + + **Covering-письмо в инбокс цели (оба канала; канон mappa-delegation).** После создания тасок — `inbox_send` получателю-проекту: таска на борде не пингует живую сессию, письмо = пинг + контекст. File channel: `mcp__mappa__inbox_send(project=, from=<своя>, subject='[event: created] тасок', body=<перечень: #N slug> )`. Service channel: то же, но `from` = своя папка (или сервисный адрес) и тело ссылается на w:NNNN-спеку. + +10. **Workshop-wiki summary (обязательно для всех маршрутов):** `Write` → `.wiki/concepts/.md` с frontmatter: @@ -370,7 +396,7 @@ write to │ (header + empty 6-section skeleton) Если `Write` упал → сообщить, **не блокировать** архивацию (summary менее критична чем content-промоушен). -10. **Архивация:** +11. **Архивация:** ```bash git -C ~/projects/.workshop mv .brainstorm/.md .archive/-.md @@ -378,7 +404,7 @@ write to │ (header + empty 6-section skeleton) **Только** если шаги 6 и 7 прошли (или прошли с допустимым partial — пользователь подтвердил). Иначе — оставить буфер на месте, чтобы можно было ретраиить. -11. **Лог:** дописать в `.wiki/log.md`: +12. **Лог:** дописать в `.wiki/log.md`: ``` promoted [created N tasks in ] @@ -386,7 +412,7 @@ write to │ (header + empty 6-section skeleton) Для skill — `` = `claude-skills/skills//SKILL.md (skeleton)`. -12. **Финальный отчёт пользователю:** +13. **Финальный отчёт пользователю:** - Куда промочено (полный путь). - Какие таски созданы (id, title, проект). - Куда уехал исходник. @@ -398,6 +424,9 @@ write to │ (header + empty 6-section skeleton) - `mcp__projects-meta` недоступен → abort до записей. - Целевой проект (для domain) не найден в `meta_status` → abort. - `knowledge_ingest` упал → abort до `tasks_create` и `git mv`. Буфер остаётся. +- **Service channel:** лиз занят (422 busy от `task_claim_next`) → abort или retry после освобождения; не писать без лиза. +- **Service channel:** `task_create` упал (гонка счётчика/переходный период) → **повторить последовательно**, не батчем; при стабильном отказе — abort до архивации. +- **Service channel:** спека уже существует в вики проекта (w:NNNN) → не дублировать `wiki_create`, ссылаться на неё. - **domain:** `tasks_create` для `[-pointers]` упал → **abort** до content-тасок и до review-таски. Без pointers оставшиеся таски бесполезны (агент будет угадывать). Сообщить пользователю; буфер оставить на месте для retry. - `tasks_create` упал на N-й content-таске → продолжить остальные. Сообщить partial. **Не делать** `git mv` без подтверждения пользователя. - `tasks_create` упал на review-таске (шаг 8) → не блокировать; перейти к архивации, сообщить пользователю чтобы создал вручную из `.archive/`. @@ -411,6 +440,7 @@ write to │ (header + empty 6-section skeleton) - **Всегда (любой маршрут):** создаёт 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` под лизом); импл-таски + 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. @@ -421,7 +451,7 @@ write to │ (header + empty 6-section skeleton) ## What NOT to do -- Не писать доменное содержимое в локальный `.wiki/concepts/` (правило #1 из `.workshop/CLAUDE.md`). Summary-страница шага 9 — это trace/навигация, не domain-контент. +- Не писать доменное содержимое в локальный `.wiki/concepts/` (правило #1 из `.workshop/CLAUDE.md`). Summary-страница шага 11 — это trace/навигация, не domain-контент. - Не пропускать шаг 9 (workshop-wiki summary) — именно так следующая сессия узнаёт что буфер был и куда ушёл. - Не делать `git mv` буфера до успеха promotion+tasks. - Не удалять буфер вместо `git mv` — теряется история. @@ -430,3 +460,6 @@ write to │ (header + empty 6-section skeleton) - **Skill:** не бампить `version` после первой записи (это работа владельца `claude-skills/`). - **Skill:** не промоутить в существующий скил (см. Failure modes — abort). - **Skill:** не пропускать обязательный preview + confirm перед `Write` — действие выходит за пределы мастерской, изменяет соседний репозиторий. +- **Service channel:** не писать в mappa-борд без лиза (422 busy); не батчить `task_create` (гонка sha-CAS счётчика, инцидент 2026-08-24: 6/7 упали) — только последовательно. +- **Service channel:** не плодить pointers-таску, если спека уже в вики проекта (w:NNNN) — описание импл-тасок ссылается на неё инлайн. +- **Service channel:** не забывать covering-письмо в инбокс цели — таска на борде не пингует живую сессию.