--- title: "Деплой каталога скилов на сервер mappa (skills-catalog deploy)" type: concept tags: [runbook, mappa, skills, catalog, deploy, ops, admin] related: [concepts/runbooks-index.md, concepts/mappa-vds-deploy-runbook.md, concepts/gitea-project-create-runbook.md] updated: 2026-08-28 --- # Деплой каталога скилов на сервер mappa > **⚙️ СЛУЖЕБНЫЙ РАНБУК — только для администратора проекта `.admin`.** > Применять/выполнять шаги может только **`.admin`** (оператор проекта admin). Другим проектам/агентам — читать по запросу, не выполнять. > Из проекта не выносить: не копировать в другие вики, не пересказывать, не публиковать. > Нужен деплой или прод-операция по этому ранбуку — **поставить задачу админу (`.admin`) и написать письмо**. Админ выполняет, остальные верифицируют. > ⚠️ **DRAFT (2026-08-28, task:1462).** Секции «Артефакты/Шаги» в части команд > заполняются после появления deploy-скриптов в каталогах-репо (mappa **task:1461**, > blocked). Scope, стоящее правило, verify/rollback/gotchas — актуальны. Решения > оператора по needs-human приняты (см. «Решения оператора»); финализация — после 1461. ## Scope Синк **каталога скилов** (skill-сущности mappa) на сервер mappa из репо-источников. Направление — **репо → mappa** (один источник истины = исходники SKILL.md в git). - Каталоги-источники (оба private, owner victor, созданы 2026-08-28 task:1458): - `victor/mappa-skills` → `kind=core` (техника, глобально); - `victor/mappa-vitya-skills` → `kind=methodology` (методология, фильтр `mappa-vitya-`). - Сервер: `mappa.vds.kzntsv.site` (стек 27, Portainer), API `/skills` (task:1375/1376). - **Деплой НЕ автоматический**: прогон только по письму-уведомлению от владельцев репо (см. «Стоящее правило») + ops-таска на борде `.admin`. ## Артефакты - **Репо-источники (clone):** - `https://git.kzntsv.site/victor/mappa-skills.git` - `https://git.kzntsv.site/victor/mappa-vitya-skills.git` - SSH-порт git.kzntsv.site — **2222** (не 22). - **Endpoint:** `https://mappa.vds.kzntsv.site/skills` — GET (список), GET `/skills/:name`, POST (create). PATCH/DELETE для `kind=core` → **403 (immutable)**. - **Токен:** `MAPPA_API_TOKEN` — `<из pass mappa/full-env>` (тот же, что env 3/3 стека mappa). - **База deploy-скриптов:** `scripts/seed-skills.ts` (засев-oneshot, task:1448 done). Deploy-скрипты в каждом каталоге-репо (task:1461) — синк изменений вместо oneshot. > DRAFT: точные команды/флаги/ENV — из README репо после 1461. - **Обратное направление (НЕ этот ранбук):** `scripts/sync-skills.ts` (task:1381) — синк каталога mappa → диск харнесса (pi/CC). Разделять: здесь деплой исходников в mappa. ## Шаги (DRAFT — команды заполнить после task:1461) 0. **Вход:** письмо-уведомление от владельцев репо (что изменилось: скилы/версии) → ops-таска на борде `.admin` (если ещё нет) → прогон по этому ранбуку. 1. **Pre-flight:** `git pull` каталога-репо; проверить, что README/скрипт 1461 на месте; `admin_secret_scan` — 0 хитов (тела скилов с секретом → 422). 2. **Dry-run:** прогнать deploy-скрипт каталога в режиме по умолчанию (`--dry-run`) → сверить план: какие скилы создаются/обновляются, нет ли неожиданного. 3. **Apply:** повторный прогон без dry-run (команда — из README репо, DRAFT). 4. **Verify** (см. ниже). 5. **Фиксация:** письмо-отчёт владельцам репо (verify-таблица) + закрытие ops-таски. > Конкретика по каждому каталогу: core-вариант (`mappa-skills`) и methodology-вариант > (`mappa-vitya-skills`, фильтр `mappa-vitya-`) — скрипты из task:1461. ## Стоящее правило: деплой при каждом изменении исходников **Прогон деплоя каталога скилов — при каждом изменении исходников в каталогах-репо.** Уведомление — **письмом от владельцев репо** (mappa-зона — держатель исходников). 1. Проект, который пушит изменения в каталог-репо, при каждом замерженном изменении исходников (новый SKILL.md / правка / удаление) шлёт письмо-уведомление в `.admin` (`inbox_send`, from проект-владелец, type action): какие скилы затронуты, что изменилось. Адресант НЕ фиксирован на проекте («кто пришлёт, тот и держатель»): сейчас mappa → mappa-skills (core), skills → mappa-vitya-skills (methodology); сменится владелец каталога — сменится адресант. 2. `.admin` по письму: ops-таска (при необходимости) → прогон деплоя по этому ранбуку (dry-run → apply → verify) → письмо-отчёт + закрытие таски. 3. Триггер — **только письмо**. Без CI/крона/автоматики (подтверждено оператором 2026-08-28). ## Verify / smoke - `GET https://mappa.vds.kzntsv.site/skills` (с `MAPPA_API_TOKEN`) — затронутые скилы присутствуют, `version` = актуальная (из frontmatter SKILL.md), `enabled:true`. - Прогон без ошибок (created/updated без 4xx/5xx; ошибки → в письме). - Потребительская сторона: `sync-skills.ts` подхватит обновления на дисках харнессов (методология — после `/reload`, спека wiki:3300 п.11) — это verify-контур, не часть деплоя. ## Rollback - **Откат содержимого:** revert коммита в репо-источнике → повторный прогон деплоя (пересинк вернёт прежнее состояние, если механизм обновления 1461 это позволяет). - **Удаление ошибочного скила:** `kind=methodology` — DELETE /skills; `kind=core` — **403**, удаление только через механизм 1461 (перезасев/иной путь) или фикс исходника. > DRAFT: уточнить после 1461. ## Gotchas 1. **`kind=core` immutable** — PATCH/DELETE `/skills` → 403. Это **пробел сервера**, не «ограничение + ручной шаг» как финал: core обязаны обновляться деплоем по определённому пути → follow-up на доработку `/skills` (требование внесено в task:1461). Ранбук фиксирует финальный механизм, когда 1461 его определит (до этого — DRAFT). Не пытаться PATCH'ить core напрямую. (2026-08-28, решения оператора inbox:2620) 2. **422 secret-scan** — тело SKILL.md с секретом (token/password/… ≥6 симв.) → `POST /skills` → 422. Перед деплоем прогон `mcp__mappa__admin_secret_scan` (0 hits). 3. **Направление не путать** — репо → mappa (этот ранбук, deploy) vs mappa → диск (`sync-skills.ts`). Перепутать = «обновление с диска» не имеет смысла: каталог — источник, диск — потребитель. (2026-08-28) 4. **Триггер письмом, не таской** — таска на борде .admin не пингует живую сессию; уведомление = письмо (канон mappa-messaging). Без письма деплой не стартует. (2026-08-28) ## Решения оператора (2026-08-28, inbox:2620) 1. **Стоящее правило** — подтверждено как сформулировано: деплой каталога при каждом изменении исходников; уведомление письмом → ops-таска → dry-run → apply → verify; триггер только письмом, без CI/автоматики. 2. **Адресант уведомлений** — НЕ фиксировать на проекте: «кто пришлёт, тот и держатель». Проект, пушащий изменения в каталог-репо, шлёт письмо в .admin. Сейчас: mappa (core), skills (methodology); сменится владелец каталога — сменится адресант. 3. **Обновление core (immutable)** — ДОДЕЛАТЬ: core должны обновляться деплоем по определённому пути. 403 = пробел сервера → follow-up на доработку /skills (требование внесено в task:1461), не «ограничение + ручной шаг» как финал. Ранбук фиксирует финальный механизм после 1461 (до этого — плейсхолдер DRAFT). **Статус:** ждём закрытия mappa **task:1461** → финализация ранбука + снятие blocked (task:1462).