Files
skills/skills/mappa-delegation/SKILL.md
vitya ae45a51420 feat(skills): интерактивный контракт (wiki:2660) — выпил claim/TTL/heartbeat из mappa-* скилов (#1040)
- mappa-task-work 1.0.0→1.1.0: «взять таску» = task_update(status=active, owner=<сессия>, version) + 409-retry; release = status=ready; close с version; heartbeat убран (живость из session live-ingest); MCP-таблица и loop-mode обновлены
- mappa-knowledge 1.0.0→1.1.0: wiki_create карв-аут, wiki_update version+409; лиз-секция убрана
- mappa-delegation 1.0.0→1.1.0: task_create карв-аут, close/update version+409
- mappa-brainstorm-promote 1.2.0→1.3.0: create карв-аут, 422 busy → 409-семантика
- mappa-messaging 1.0.0→1.1.0: task_create/close карв-аут + version+409
- mappa-closing-ritual: task_close version+409 (упоминания)

Откат claim-механики из скилов; контракт = wiki:2660.
2026-08-25 00:27:25 +03:00

18 KiB
Raw Blame History

name, author, version, description
name author version description
mappa-delegation ours 1.1.0 Цикл делегирования задачи другому агенту/проекту: 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-внутренние таски.

mappa-delegation

Унифицированный цикл постановки задач на агентов: от pre-flight гейта до covering-письма получателю. Гарантирует, что каждая делегированная задача содержит: обязательные скилы (императивный invoke), pre-flight разрешения, steering-loop поля (notify/weight), парную review-таску для impl — и что получатель реально узнаёт о задаче (письмо, не только борд).

When to use

Перед каждым вызовом tasks_create для другого проекта или агента.

Активируется: «делегировать таску», «delegate task», «создать задачу на агента», «поставить задачу агенту», «tasks_create для».

Не применяется:

  • Работа которую выполняешь сам в текущей сессии.
  • Self-assigned таски на своей доске («создать задачу себе», «task for myself», «поставить себе задачу») → mappa-task-work, не делегирование. Дизамбигуатор: «на агента»/«агенту»/«в проект X» = делегирование; «себе»/«myself» = своя доска.
  • Workshop-internal таски (.workshop/.tasks/ — workshop-meta, не делегирование).
  • tasks_create с target=agenda (cross-project agenda — не делегирование агенту).

Inputs

  • target_project — qualified <owner>/<repo> (обязательно)
  • slug — kebab-case latin
  • Краткое описание задачи (цель + acceptance criteria)
  • weightcheap-ok | needs-claude | needs-human
  • notify — slug проекта-комиссионера (кому писать inbox при close/park)

Номер задаче присваивает сервер (tasks_create из счётчика agenda/task-counter) — постановщик номер не придумывает и не резервирует. Возвращённый #n из preview/confirm — машинный ключ задачи: им ссылаются блокеры, письма, decision-trail.

Интерактивный контракт (wiki:2660). task_create — карв-аут, лиз НЕ нужен (create = INSERT, входной контур). task_close/task_update — optimistic version+409 (конфликт → свежая version из task_get → retry). File channel — sha-CAS через Gitea (projects-meta), там свои правила.

Steps (цикл)

1. Pre-flight gate (6 вопросов пользователю)

Спросить до составления тела задачи:

  1. Критическая инфраструктура? — задача меняет: поллер/агент-раннер, MCP серверы (projects-meta, interns), механизм claim/close/heartbeat, deploy-инфру (traefik, docker, systemd), CI/CD пайплайны, git hooks.
    • Если даweight: needs-human принудительно, без обсуждения. Объяснить пользователю почему.
    • Если нет → идти дальше.
  2. Интерны — разрешены? (да/нет, per задача)
  3. Автопуш — разрешён? (да/нет, per задача)
  4. Контекстные скилы сверх дефолтов? — предложить по содержанию задачи (например claude-api для работы с Anthropic SDK, frontend-design для UI, using-interns если интерны разрешены), пользователь утверждает.
  5. notify — кому докладывать о завершении/затыке? (slug проекта; обычно .workshop или OpeItcLoc03/workshop)
  6. Session-break после этой задачи? — нужен ли разрыв сессии после её закрытия (domain-switch, milestone, heavy infra)?
    • Если да → проставить session_break в теле задачи (см. шаблон): true или строка-hint с названием следующего трека. mappa-task-work остановится после close и предложит завершить сессию, не клеймя следующую задачу.
    • Если нет → поле не добавлять (дефолт — агент продолжает claim-next).

2. Составить тело задачи по шаблону

Секции строго по порядку:

<Цель — одно-два предложения. Acceptance criteria если есть.>
**Спека:** <path к design-решению или .brainstorm/…> — обязательно для задач
из дизайна/решения: импл читает дизайн, не угадывает

## Обязательные скилы — вызвать до начала работы

- invoke `tdd-criteria` — до написания кода
- invoke `mappa-task-work` — для управления статусом задачи
- invoke `project-discipline` — дисциплина коммитов/пушей
- invoke `mappa-knowledge` после закрытия — заингесть .wiki/concepts/<slug>.md
[если кросс-проектная: - invoke `using-projects-meta` — cross-project tasks/wiki]
[контекстные скилы из шага 1.3]

**TDD:** да | нет — <причина>
**Разрешения:** интерны: да/нет | автопуш: да/нет
**weight:** cheap-ok | needs-claude | needs-human
**notify:** <commissioning-project-slug>
[**allow_upgrade:** true/false]
[**session_break:** true | "<следующий трек / hint>"]   # optional — mappa-task-work остановится после close, не клеймит следующую задачу

Когда ставить session_break (опционально; по умолчанию НЕ ставить — это маркер реальной границы, не дефолт). Три случая:

  1. Смена домена / репо — задача завершает один трек перед переходом на несвязанный.
  2. Milestone-задача — последняя в группе sub-tasks одной фичи.
  3. Тяжёлая инфра-задача — shared checkout, migrations, deploy — где разумно остановиться и проверить состояние.

Значение: true (следующий трек = «см. STATUS.md») либо строка-hint с названием следующего трека. Потребитель — mappa-task-work: после close печатает 🔚 SESSION BOUNDARY … и останавливается, не клеймя следующую задачу. Дизайн: .wiki/concepts/delegate-task-session-break.md.

Этапные цепочки (staged breakdown): если решение бьётся на этапы (1 → 1b → 3), создавай каждый этап отдельной таской со status: blocked + blocker: <номера-предшественников> (#n1, #n2 — номера, не слаги; номер = машинный ключ). Доска показывает порядок, поллер не возьмёт зависимую работу раньше времени. Таски в один репо создавай последовательно, не параллельно (иначе sha-lock конфликт — см. Failure modes).

Почему invoke а не триггер-фраза: AGENTS.md ненадёжен (уплывает при compression, слабые модели игнорируют). Тело задачи читается активно — императив invoke это прямая команда, не пассивный матчинг.

3. Dry-run preview

tasks_create(confirm=false) — показать пользователю preview до реального коммита.

4. Подтверждение и создание

После OK пользователя: tasks_create(confirm=true).

5. Сопроводительное письмо — обязательно при кросс-проектной делегации

После создания каждая кросс-проектная делегация дублируется письмом в инбокс получателя (канон — mappa-messaging: канал Mappa, адрес из адресной книги ~/projects/.wiki/concepts/projects-address-book.md):

mcp__mappa__inbox_send(
  project: <адрес-получателя>,   # имя папки, из адресной книги
  from:    <своя-папка>,
  subject: "[event: created] #n slug",
  body:    "1-2 строки — что за задача, почему, slug; «разбери и возьми»"
)

(task_create — карв-аут (wiki:2660), доставка письма — карв-аут.)

Причина: таска на борде не пингует живую сессию получателя. Поллер подхватит по Weight/Notify, но живая интерактивная сессия узнаёт только через inbox-монитор — т.е. через письмо. Правило «task + letter, не только task» — общий случай (шаг 7 — его частность для downstream-задач).

Пропуск: self-assigned задачи на своей доске; target=agenda (общая доска, конкретного получателя нет — steering-loop через Notify).

6. Парная review-таска (только для impl-задач)

Если задача имплементационная — создать парную <slug>-review (status=blocked, blocker=#n — номер impl-таски). Пропустить для: pointers-тасок, ops-тасок, research-тасок, любых non-impl.

weight review-таски — наследовать от impl-таски, но не ниже needs-claude (проставлять явно при tasks_create):

  • impl needs-human → review needs-human (критично-инфраструктурное изменение нельзя ревьюить слабым tier'ом — ревью наследует строгость impl).
  • impl needs-claude → review needs-claude.
  • impl cheap-ok → review needs-claude (флор: review дисциплинарно-критична, см. What NOT to do — cheap-ok сюда не опускать).

Без явного weight поллер не маршрутизирует review-таску (reconciler её пропускает) — поэтому проставлять всегда, даже когда impl и review совпадают по tier'у.

7. Downstream-задача для ЖИВОЙ сессии → требовать task + inbox-письмо

Если тело задачи поручает агенту самому создать downstream-задачу для другого проекта, где работает живая интерактивная сессия (напр. прог сам ставит deploy-таску админу), — в ТЗ явно потребуй И tasks_create, И inbox-письмо тому проекту (mcp__mappa__inbox_send(project=<target>, from=<своя>, subject="[event: created] #n slug", ...)).

Причина: таска на борде живую сессию НЕ пингует. Поллер подхватит по Weight/Notify, но живая интерактивная сессия узнаёт только через inbox-монитор / Stop-хук — т.е. через письмо. ТЗ, требующее лишь tasks_create, оставляет downstream-таску висеть незамеченной, и кто-то доделывает пинг руками.

Правило: poller-driven таргет → Weight/Notify обязательны; live-сессия → inbox-письмо обязательно; не уверен, поллер или живой — требуй ОБА. Это же правило применяй, когда пингуешь пира сам: task + letter, не только 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 без явного запроса.

Side effects

  • Создаёт таску в target-проекте через tasks_create (file channel — Gitea commit; service channel — mappa-сущность карв-аутом, wiki:2660).
  • Опционально создаёт парную review-таску (status=blocked).
  • Covering-письмо в инбокс получателя (кросс-проектная делегация).

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-таска висит незамеченной.

Reference

  • Письма: mappa-messaging (канон inbox_send, адресная книга).
  • Задачи/борд: mappa-task-work.
  • Знание: mappa-knowledge (wiki после закрытия).
  • Промоушен: mappa-brainstorm-promote (review-umbrella через него же).