From 76ff6ad3fc1e8903a68e91266f8233337ff344d3 Mon Sep 17 00:00:00 2001 From: vitya Date: Tue, 25 Aug 2026 17:42:35 +0300 Subject: [PATCH] =?UTF-8?q?docs(skills):=20mappa-delegation=201.2.0?= =?UTF-8?q?=E2=86=921.3.0=20=E2=80=94=20English=20translation,=20bilingual?= =?UTF-8?q?=20triggers=20(task:1086)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/mappa-delegation/SKILL.md | 314 ++++++++++++++++++------------- 1 file changed, 183 insertions(+), 131 deletions(-) diff --git a/skills/mappa-delegation/SKILL.md b/skills/mappa-delegation/SKILL.md index 3c22967..25a6ec4 100644 --- a/skills/mappa-delegation/SKILL.md +++ b/skills/mappa-delegation/SKILL.md @@ -1,209 +1,261 @@ --- name: mappa-delegation author: ours -version: 1.2.0 +version: 1.3.0 description: > - Цикл делегирования задачи другому агенту/проекту: pre-flight gate → - шаблон тела → dry-run preview → confirm → covering-письмо в инбокс - получателя → парная review-таска для impl. Каждая кросс-проектная делегация - — пара: tasks_create + письмо (event: created) — таска на борде не пингует - живую сессию. Старое имя — триггер-синоним: delegate-task. Триггеры: - «делегировать таску», «delegate task», «создать задачу на агента», - «поставить задачу агенту», «tasks_create для». НЕ применимо: self-assigned - таски на своей доске («создать задачу себе» → mappa-task-work), работа - своими руками, workshop-внутренние таски. + The cycle of delegating a task to another agent/project: pre-flight gate → + body template → dry-run preview → confirm → covering letter to the + recipient's inbox → paired review task for impl. Every cross-project + delegation is a pair: tasks_create + letter (event: created) — a task on the + board does not ping a live session. Old name — trigger-synonym: + delegate-task. Triggers (bilingual): «делегировать таску», «создать задачу + на агента», «поставить задачу агенту», «tasks_create для», "delegate task", + "create a task for an agent", "assign a task to an agent". NOT applicable: + self-assigned tasks on your own board («создать задачу себе» → + mappa-task-work), doing work yourself, workshop-internal tasks. --- # mappa-delegation -Унифицированный **цикл постановки задач на агентов**: от pre-flight гейта до -covering-письма получателю. Гарантирует, что каждая делегированная задача -содержит: обязательные скилы (императивный invoke), pre-flight разрешения, -steering-loop поля (notify/weight), парную review-таску для impl — и что -получатель реально узнаёт о задаче (письмо, не только борд). +Unified **cycle of assigning tasks to agents**: from the pre-flight gate to +the covering letter to the recipient. Guarantees that every delegated task +carries: mandatory skills (imperative invoke), pre-flight permissions, +steering-loop fields (notify/weight), a paired review task for impl — and that +the recipient actually learns about the task (letter, not just the board). ## When to use -Перед каждым вызовом `tasks_create` для другого проекта или агента. +Before every `tasks_create` call for another project or agent. -**Активируется:** «делегировать таску», «delegate task», «создать задачу на агента», «поставить задачу агенту», «tasks_create для». +**Activates:** «делегировать таску», «создать задачу на агента», «поставить задачу агенту», «tasks_create для», "delegate task", "create a task for an agent". -**Не применяется:** -- Работа которую выполняешь сам в текущей сессии. -- Self-assigned таски на своей доске («создать задачу себе», «task for myself», «поставить себе задачу») → `mappa-task-work`, не делегирование. Дизамбигуатор: «на агента»/«агенту»/«в проект X» = делегирование; «себе»/«myself» = своя доска. -- Workshop-internal таски (`.workshop/.tasks/` — workshop-meta, не делегирование). -- `tasks_create` с `target=agenda` (cross-project agenda — не делегирование агенту). +**Not applicable:** +- Work you do yourself in the current session. +- Self-assigned tasks on your own board («создать задачу себе», "task for myself") → `mappa-task-work`, not delegation. Disambiguator: «на агента»/«агенту»/«в проект X» = delegation; «себе»/"myself" = your own board. +- Workshop-internal tasks (`.workshop/.tasks/` — workshop-meta, not delegation). +- `tasks_create` with `target=agenda` (cross-project agenda — not delegation to an agent). ## Inputs -- `target_project` — qualified `/` (обязательно) +- `target_project` — qualified `/` (required) - `slug` — kebab-case latin -- Краткое описание задачи (цель + acceptance criteria) +- Short task description (goal + acceptance criteria) - `weight` — `cheap-ok | needs-claude | needs-human` -- `notify` — slug проекта-комиссионера (кому писать inbox при close/park) +- `notify` — commissioning project slug (who gets the inbox letter on close/park) -Номер задаче присваивает сервер (`tasks_create` из счётчика agenda/task-counter) — постановщик номер не придумывает и не резервирует. Возвращённый `#n` из preview/confirm — машинный ключ задачи: им ссылаются блокеры, письма, decision-trail. +The task number is assigned by the server (`tasks_create` from the +agenda/task-counter) — the assigner neither invents nor reserves it. The +returned `#n` from preview/confirm is the task's machine key: blockers, +letters, and the decision trail reference it. -> **Контракт (interactive, wiki:2660).** `task_create` — **карв-аут без -> лиза** (create-без-лиза как принцип); update/close — version+409 (409 → -> re-GET → retry). file channel — sha-CAS через Gitea. Claim/TTL нет — -> «взять таску» = conditional update по version (поллер вне mappa). +> **Contract (interactive, wiki:2660).** `task_create` — **carve-out without a +> lease** (create-without-lease as a principle); update/close — version+409 +> (409 → re-GET → retry). file channel — sha-CAS via Gitea. No claim/TTL — +> "take a task" = conditional update by version (poller outside mappa). -## Steps (цикл) +## Steps (the cycle) -### 1. Pre-flight gate (6 вопросов пользователю) +### 1. Pre-flight gate (6 questions to the user) -Спросить **до** составления тела задачи: +Ask **before** composing the task body: -0. **Критическая инфраструктура?** — задача меняет: поллер/агент-раннер, MCP серверы (projects-meta, interns), механизм claim/close/heartbeat, deploy-инфру (traefik, docker, systemd), CI/CD пайплайны, git hooks. - - Если **да** → `weight: needs-human` принудительно, без обсуждения. Объяснить пользователю почему. - - Если **нет** → идти дальше. -1. **Интерны — разрешены?** (да/нет, per задача) -2. **Автопуш — разрешён?** (да/нет, per задача) -3. **Контекстные скилы сверх дефолтов?** — предложить по содержанию задачи (например `claude-api` для работы с Anthropic SDK, `frontend-design` для UI, `using-interns` если интерны разрешены), пользователь утверждает. -4. **notify — кому докладывать о завершении/затыке?** (slug проекта; обычно `.workshop` или `OpeItcLoc03/workshop`) -5. **Session-break после этой задачи?** — нужен ли разрыв сессии после её закрытия (domain-switch, milestone, heavy infra)? - - Если **да** → проставить `session_break` в теле задачи (см. шаблон): `true` или строка-hint с названием следующего трека. `mappa-task-work` остановится после close и предложит завершить сессию, не клеймя следующую задачу. - - Если **нет** → поле не добавлять (дефолт — агент продолжает цикл). +0. **Critical infrastructure?** — the task changes: poller/agent-runner, MCP + servers (projects-meta, interns), claim/close/heartbeat mechanics, deploy + infra (traefik, docker, systemd), CI/CD pipelines, git hooks. + - If **yes** → force `weight: needs-human`, no discussion. Explain to the + user why. + - If **no** → continue. +1. **Interns — allowed?** (yes/no, per task) +2. **Auto-push — allowed?** (yes/no, per task) +3. **Contextual skills beyond defaults?** — propose per task content (e.g. + `claude-api` for Anthropic SDK work, `frontend-design` for UI, + `using-interns` if interns are allowed); the user approves. +4. **notify — who gets the completion/block report?** (project slug; usually + `.workshop` or `OpeItcLoc03/workshop`) +5. **Session-break after this task?** — is a session break needed after it + closes (domain-switch, milestone, heavy infra)? + - If **yes** → set `session_break` in the task body (see template): `true` + or a string-hint with the next track's name. `mappa-task-work` will stop + after close and propose ending the session, without claiming the next task. + - If **no** → don't add the field (default — the agent continues the cycle). -### 2. Составить тело задачи по шаблону +### 2. Compose the task body per template -Секции строго по порядку: +Sections strictly in order: ``` -<Цель — одно-два предложения. Acceptance criteria если есть.> -**Спека:** — обязательно для задач -из дизайна/решения: импл читает дизайн, не угадывает + +**Spec:** — mandatory for tasks +from design/decision: the impl reads the design, doesn't guess -## Обязательные скилы — вызвать до начала работы +## Mandatory skills — invoke before starting work -- invoke `tdd-criteria` — до написания кода -- invoke `mappa-task-work` — для управления статусом задачи -- invoke `project-discipline` — дисциплина коммитов/пушей -- invoke `mappa-knowledge` после закрытия — заингесть .wiki/concepts/.md -[если кросс-проектная: - invoke `using-projects-meta` — cross-project tasks/wiki] -[контекстные скилы из шага 1.3] +- invoke `tdd-criteria` — before writing code +- invoke `mappa-task-work` — for task status management +- invoke `project-discipline` — commit/push discipline +- invoke `mappa-knowledge` after closing — ingest .wiki/concepts/.md +[if cross-project: - invoke `using-projects-meta` — cross-project tasks/wiki] +[contextual skills from step 1.3] -**TDD:** да | нет — <причина> -**Разрешения:** интерны: да/нет | автопуш: да/нет +**TDD:** yes | no — +**Permissions:** interns: yes/no | auto-push: yes/no **weight:** cheap-ok | needs-claude | needs-human **notify:** [**allow_upgrade:** true/false] -[**session_break:** true | "<следующий трек / hint>"] # optional — mappa-task-work остановится после close, не клеймит следующую задачу +[**session_break:** true | ""] # optional — mappa-task-work stops after close, doesn't claim the next task ``` -**Когда ставить `session_break`** (опционально; по умолчанию НЕ ставить — это маркер реальной границы, не дефолт). Три случая: +**When to set `session_break`** (optional; by default DON'T set it — it marks +a real boundary, not a default). Three cases: -1. **Смена домена / репо** — задача завершает один трек перед переходом на несвязанный. -2. **Milestone-задача** — последняя в группе sub-tasks одной фичи. -3. **Тяжёлая инфра-задача** — shared checkout, migrations, deploy — где разумно остановиться и проверить состояние. +1. **Domain / repo switch** — the task finishes one track before moving to an + unrelated one. +2. **Milestone task** — the last in a group of sub-tasks of one feature. +3. **Heavy infra task** — shared checkout, migrations, deploy — where it's + reasonable to stop and check the state. -Значение: `true` (следующий трек = «см. STATUS.md») либо строка-hint с названием следующего трека. Потребитель — `mappa-task-work`: после close печатает `🔚 SESSION BOUNDARY …` и останавливается, не клеймя следующую задачу. Дизайн: `.wiki/concepts/delegate-task-session-break.md`. +Value: `true` (next track = "see STATUS.md") or a string-hint with the next +track's name. Consumer — `mappa-task-work`: after close it prints +`🔚 SESSION BOUNDARY …` and stops, without claiming the next task. Design: +`.wiki/concepts/delegate-task-session-break.md`. -**Этапные цепочки (staged breakdown):** если решение бьётся на этапы -(1 → 1b → 3), создавай каждый этап отдельной таской со `status: blocked` + -`blocker: <номера-предшественников> (#n1, #n2 — номера, не слаги; номер = -машинный ключ)`. Доска показывает порядок, поллер не возьмёт зависимую -работу раньше времени. Таски в один репо создавай последовательно, не -параллельно (иначе sha-lock конфликт — см. Failure modes). +**Staged breakdown:** if the solution splits into stages (1 → 1b → 3), create +each stage as a separate task with `status: blocked` + `blocker: + (#n1, #n2 — numbers, not slugs; the number = machine +key)`. The board shows the order, the poller won't take dependent work early. +Create tasks in one repo sequentially, not in parallel (otherwise sha-lock +conflict — see Failure modes). -**Почему `invoke` а не триггер-фраза:** AGENTS.md ненадёжен (уплывает при compression, слабые модели игнорируют). Тело задачи читается активно — императив `invoke` это прямая команда, не пассивный матчинг. +**Why `invoke` and not a trigger phrase:** AGENTS.md is unreliable (drifts +under compression, weak models ignore it). The task body is read actively — +the imperative `invoke` is a direct command, not passive matching. ### 3. Dry-run preview -`tasks_create(confirm=false)` — показать пользователю preview до реального коммита. +`tasks_create(confirm=false)` — show the user the preview before the real commit. -### 4. Подтверждение и создание +### 4. Confirmation and creation -После OK пользователя: `tasks_create(confirm=true)`. +After the user's OK: `tasks_create(confirm=true)`. -### 5. Сопроводительное письмо — обязательно при кросс-проектной делегации +### 5. Covering letter — mandatory for cross-project delegation -После создания **каждая кросс-проектная делегация** дублируется письмом в -инбокс получателя (канон — `mappa-messaging`: канал Mappa, адрес из адресной -книги `~/projects/.wiki/concepts/projects-address-book.md`): +After creation, **every cross-project delegation** is duplicated by a letter to +the recipient's inbox (canon — `mappa-messaging`: Mappa channel, address from +the address book `~/projects/.wiki/concepts/projects-address-book.md`): ``` mcp__mappa__inbox_send( - project: <адрес-получателя>, # имя папки, из адресной книги - from: <своя-папка>, + project: , # folder name, from the address book + from: , subject: "[event: created] #n slug", - body: "1-2 строки — что за задача, почему, slug; «разбери и возьми»" + body: "1-2 lines — what the task is, why, slug; «sort it out and take it»" ) ``` -(Мутации update/close — version-based (409 → retry); доставка письма — -карв-аут, лиза не требует.) +(update/close mutations — version-based (409 → retry); letter delivery — +carve-out, requires no lease.) -Причина: таска на борде **не пингует живую сессию** получателя. Поллер -подхватит по `Weight`/`Notify`, но живая интерактивная сессия узнаёт только -через inbox-монитор — т.е. через письмо. Правило «task + letter, не только -task» — общий случай (шаг 7 — его частность для downstream-задач). +Reason: a task on the board **does not ping the recipient's live session**. +The poller will pick it up by `Weight`/`Notify`, but a live interactive +session learns only through the inbox monitor — i.e. through the letter. The +rule "task + letter, not just task" — is the general case (step 7 is its +particular case for downstream tasks). -Пропуск: self-assigned задачи на своей доске; `target=agenda` (общая доска, -конкретного получателя нет — steering-loop через `Notify`). +Skip: self-assigned tasks on your own board; `target=agenda` (shared board, +no concrete recipient — steering-loop via `Notify`). -### 6. Парная review-таска (только для impl-задач) +### 6. Paired review task (impl tasks only) -Если задача имплементационная — создать парную `-review` (status=blocked, blocker=`#n` — номер impl-таски). Пропустить для: pointers-тасок, ops-тасок, research-тасок, любых non-impl. +If the task is implementation — create the paired `-review` +(status=blocked, blocker=`#n` — the impl task number). Skip for: pointer +tasks, ops tasks, research tasks, any non-impl. -**`weight` review-таски — наследовать от impl-таски, но не ниже `needs-claude`** (проставлять явно при `tasks_create`): +**`weight` of the review task — inherit from the impl task, but never below +`needs-claude`** (set explicitly at `tasks_create`): -- impl `needs-human` → review `needs-human` (критично-инфраструктурное изменение нельзя ревьюить слабым tier'ом — ревью наследует строгость impl). +- impl `needs-human` → review `needs-human` (a critical-infra change cannot + be reviewed by a weak tier — the review inherits the impl's strictness). - impl `needs-claude` → review `needs-claude`. -- impl `cheap-ok` → review `needs-claude` (флор: review дисциплинарно-критична, см. What NOT to do — cheap-ok сюда не опускать). +- impl `cheap-ok` → review `needs-claude` (floor: review is + discipline-critical, see What NOT to do — don't drop to cheap-ok). -Без явного `weight` поллер не маршрутизирует review-таску (reconciler её пропускает) — поэтому проставлять всегда, даже когда impl и review совпадают по tier'у. +Without an explicit `weight` the poller won't route the review task (the +reconciler skips it) — so always set it, even when impl and review are at the +same tier. -### 7. Downstream-задача для ЖИВОЙ сессии → требовать task + inbox-письмо +### 7. Downstream task for a LIVE session → require task + inbox letter -Если тело задачи **поручает агенту самому создать downstream-задачу** для другого проекта, где работает **живая интерактивная сессия** (напр. прог сам ставит deploy-таску админу), — в ТЗ **явно потребуй И `tasks_create`, И inbox-письмо** тому проекту (`mcp__mappa__inbox_send(project=, from=<своя>, subject="[event: created] #n slug", ...)`). +If the task body **instructs the agent to create a downstream task itself** for +another project where a **live interactive session** is working (e.g. the +programmer sets a deploy task for the admin) — in the spec **explicitly require +BOTH `tasks_create` AND the inbox letter** to that project +(`mcp__mappa__inbox_send(project=, from=, subject="[event: created] #n slug", ...)`). -Причина: таска на борде живую сессию **НЕ пингует**. Поллер подхватит по `Weight`/`Notify`, но живая интерактивная сессия узнаёт только через inbox-монитор / Stop-хук — т.е. через письмо. ТЗ, требующее лишь `tasks_create`, оставляет downstream-таску висеть незамеченной, и кто-то доделывает пинг руками. +Reason: a task on the board does **NOT** ping the live session. The poller +will pick it up by `Weight`/`Notify`, but a live interactive session learns +only through the inbox monitor / Stop-hook — i.e. through the letter. A spec +that requires only `tasks_create` leaves the downstream task hanging unnoticed, +and someone finishes the ping by hand. -Правило: poller-driven таргет → `Weight`/`Notify` обязательны; live-сессия → inbox-письмо обязательно; **не уверен, поллер или живой — требуй ОБА.** Это же правило применяй, когда пингуешь пира сам: task + letter, не только task. +Rule: poller-driven target → `Weight`/`Notify` mandatory; live session → inbox +letter mandatory; **not sure poller or live — require BOTH.** Apply the same +rule when you ping a peer yourself: task + letter, not just task. ## Failure modes -- **Пользователь отказывает на pre-flight** → abort, задачу не создавать. -- **Пользователь отклоняет dry-run preview** → abort. -- **notify не указан** → переспросить, не пропускать молча. Без notify steering-loop не замыкается. -- **weight не указан** → переспросить. Без weight поллер не знает кому отдать задачу. -- **tasks_create упал** → различить: **PushRejected** (sha-lock конфликт — - репо уехало между preview и confirm; бывает при параллельном создании в один - репо) → **retry**: повторить confirm — сервер перечитает актуальный base_sha. - Другие ошибки → сообщить пользователю, не делать retry без явного запроса. +- **User refuses the pre-flight** → abort, don't create the task. +- **User rejects the dry-run preview** → abort. +- **notify not specified** → re-ask, don't skip silently. Without notify the + steering-loop doesn't close. +- **weight not specified** → re-ask. Without weight the poller doesn't know who + to give the task to. +- **tasks_create failed** → distinguish: **PushRejected** (sha-lock conflict — + the repo moved between preview and confirm; happens on parallel creation into + one repo) → **retry**: repeat the confirm — the server re-reads the actual + base_sha. Other errors → tell the user, don't retry without an explicit request. ## Side effects -- Создаёт таску в target-проекте через `tasks_create` (file channel — Gitea commit; service channel — mappa-сущность, create = карв-аут без лиза wiki:2660). -- Опционально создаёт парную review-таску (status=blocked). -- Covering-письмо в инбокс получателя (кросс-проектная делегация). +- Creates a task in the target project via `tasks_create` (file channel — + Gitea commit; service channel — mappa entity, create = carve-out without a + lease wiki:2660). +- Optionally creates the paired review task (status=blocked). +- Covering letter to the recipient's inbox (cross-project delegation). ## What NOT to do -- Не пропускать pre-flight gate — даже если кажется что всё очевидно. -- Не использовать пассивные триггер-фразы вместо `invoke` — «tdd-criteria» в тексте слабее чем «invoke `tdd-criteria`». -- Не пропускать `notify` — без него boss не узнает о завершении. -- Не пропускать `weight` — без него fleet routing слеп. -- Не создавать review-таску для pointers/ops/research задач — только для impl. -- Не создавать review-таску без `weight` — reconciler/поллер её пропустит. Наследовать от impl, флор `needs-claude` (см. Step 6). -- Не назначать `weight: cheap-ok` для задач где дисциплина критична (review, security, schema migration) — слабые модели могут игнорировать invoke-инструкции. -- Не назначать `weight: needs-claude` или `cheap-ok` задачам, меняющим критическую инфраструктуру (поллер, MCP серверы, deploy, CI/CD) — только `needs-human`. -- Не ставить `session_break` рутинно на каждую задачу — это маркер реальной границы (domain-switch / milestone / heavy infra), не дефолт; иначе `mappa-task-work` рвёт сессию после каждого close. -- **Не создавать задачи из дизайна/решения без `**Спека:**`-ссылки** — - импл-агент угадывает пороги/скоуп вместо чтения дизайна. -- **Не создавать несколько тасок в один репо параллельно** — sha-lock - конфликты (PushRejected); сериализуй confirm'ы. -- **Не делегировать кросс-проектную задачу без сопроводительного письма** в - инбокс получателя (шаг 5, Mappa `inbox_send`). `tasks_create` в чужой борд - живую сессию не пингует — task без letter остаётся незамеченной до - поллера/руки. -- **Не поручать агенту создать downstream-таску для живой сессии без парного inbox-письма** (см. Step 7). `tasks_create` в чужой борд живую сессию не пингует — ТЗ обязано требовать И таску, И письмо, иначе downstream-таска висит незамеченной. +- Don't skip the pre-flight gate — even if everything seems obvious. +- Don't use passive trigger phrases instead of `invoke` — "tdd-criteria" in + text is weaker than "invoke `tdd-criteria`". +- Don't skip `notify` — without it the boss won't learn about completion. +- Don't skip `weight` — without it fleet routing is blind. +- Don't create a review task for pointer/ops/research tasks — impl only. +- Don't create a review task without `weight` — the reconciler/poller will + skip it. Inherit from impl, floor `needs-claude` (see Step 6). +- Don't assign `weight: cheap-ok` where discipline is critical (review, + security, schema migration) — weak models may ignore invoke instructions. +- Don't assign `weight: needs-claude` or `cheap-ok` to tasks changing critical + infrastructure (poller, MCP servers, deploy, CI/CD) — only `needs-human`. +- Don't set `session_break` routinely on every task — it marks a real + boundary (domain-switch / milestone / heavy infra), not a default; otherwise + `mappa-task-work` breaks the session after every close. +- **Don't create tasks from design/decision without a `**Spec:**` reference** + — the impl agent guesses thresholds/scope instead of reading the design. +- **Don't create several tasks in one repo in parallel** — sha-lock conflicts + (PushRejected); serialize the confirms. +- **Don't delegate a cross-project task without the covering letter** to the + recipient's inbox (step 5, Mappa `inbox_send`). `tasks_create` into a foreign + board doesn't ping the live session — a task without a letter stays unnoticed + until the poller/hand. +- **Don't instruct the agent to create a downstream task for a live session + without the paired inbox letter** (see Step 7). `tasks_create` into a foreign + board doesn't ping the live session — the spec must require BOTH the task + and the letter, otherwise the downstream task hangs unnoticed. ## Reference -- Письма: `mappa-messaging` (канон inbox_send, адресная книга). -- Задачи/борд: `mappa-task-work`. -- Знание: `mappa-knowledge` (wiki после закрытия). -- Промоушен: `mappa-brainstorm-promote` (review-umbrella через него же). +- Letters: `mappa-messaging` (inbox_send canon, address book). +- Tasks/board: `mappa-task-work`. +- Knowledge: `mappa-knowledge` (wiki after closing). +- Promotion: `mappa-brainstorm-promote` (review-umbrella through it too).