- inter-session-messaging v2.0.0: channel switched from file inbox (.agents/inbox/) to Mappa inbox.send/inbox.monitor/entity_get; letters are entities i:N, delivery is a lease carve-out; address book + project-exists check via admin_status; replies via entity_get(id).meta.from; subject carries [event: ...] instead of frontmatter. - session-inbox-monitor v1.0.0: monitor now polls GET /inbox?project=<cwd> (HTTP, dedup by letter id, no .read/ move); hook inbox-monitor.ps1 rewritten to inject the mappa poll command (sweep sentinel + project dir). - delegate-task v0.5.1: covering letter goes through inbox_send, not file path. Part of #983 (mappa-skills).
194 lines
17 KiB
Markdown
194 lines
17 KiB
Markdown
---
|
||
name: delegate-task
|
||
author: ours
|
||
version: 0.5.1
|
||
description: >
|
||
Use when delegating a task to another agent or project via
|
||
mcp__projects-meta__tasks_create. Every cross-project delegation is a
|
||
pair: tasks_create + covering letter to the recipient's inbox (event:
|
||
created) — a task on the board does not ping a live session. Triggers:
|
||
«делегировать таску», «delegate task», «создать задачу на агента»,
|
||
«поставить задачу агенту», «tasks_create для». Does NOT apply to
|
||
self-assigned tasks on your own board («создать задачу себе», «task for
|
||
myself», «поставить себе задачу» → using-tasks), to work you do yourself,
|
||
or to workshop-internal tasks.
|
||
---
|
||
|
||
# delegate-task
|
||
|
||
Унифицированный формат постановки задач на агентов через `mcp__projects-meta__tasks_create`. Обеспечивает что каждая делегированная задача содержит: обязательные скилы (императивный invoke), pre-flight разрешения, steering-loop поля (notify/weight/allow_upgrade).
|
||
|
||
## When to use
|
||
|
||
Перед каждым вызовом `mcp__projects-meta__tasks_create` для другого проекта или агента.
|
||
|
||
**Активируется:** «делегировать таску», «delegate task», «создать задачу на агента», «поставить задачу агенту», «tasks_create для».
|
||
|
||
**Не применяется:**
|
||
- Работа которую выполняешь сам в текущей сессии.
|
||
- Self-assigned таски на своей доске («создать задачу себе», «task for myself», «поставить себе задачу») → `using-tasks`, не делегирование. Дизамбигуатор: «на агента»/«агенту»/«в проект 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)
|
||
- `weight` — `cheap-ok | needs-claude | needs-human`
|
||
- `notify` — slug проекта-комиссионера (кому писать inbox при close/park)
|
||
- `allow_upgrade` — `true/false` (опционально; разрешить ли fallback на tier выше если нет matching backend)
|
||
|
||
Номер задаче присваивает сервер (`tasks_create` из счётчика `OpeItcLoc03/agenda/task-counter`) — постановщик номер не придумывает и не резервирует. Возвращённый `#n` из preview/confirm — машинный ключ задачи: им ссылаются блокеры, письма, decision-trail.
|
||
|
||
## Steps
|
||
|
||
### 1. Pre-flight gate (6 вопросов пользователю)
|
||
|
||
Спросить **до** составления тела задачи:
|
||
|
||
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 с названием следующего трека. `using-tasks` остановится после close и предложит завершить сессию, не клеймя следующую задачу.
|
||
- Если **нет** → поле не добавлять (дефолт — агент продолжает `claim-next`).
|
||
|
||
### 2. Составить тело задачи по шаблону
|
||
|
||
Секции строго по порядку:
|
||
|
||
```
|
||
<Цель — одно-два предложения. Acceptance criteria если есть.>
|
||
**Спека:** <path к design-решению или .brainstorm/…> — обязательно для задач
|
||
из дизайна/решения: импл читает дизайн, не угадывает
|
||
|
||
## Обязательные скилы — вызвать до начала работы
|
||
|
||
- invoke `tdd-criteria` — до написания кода
|
||
- invoke `using-tasks` — для управления статусом задачи
|
||
- invoke `project-discipline` — дисциплина коммитов/пушей
|
||
- invoke `using-wiki` после закрытия — заингесть .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 — using-tasks остановится после close, не клеймит следующую задачу
|
||
```
|
||
|
||
**Когда ставить `session_break`** (опционально; по умолчанию НЕ ставить — это маркер реальной границы, не дефолт). Три случая:
|
||
|
||
1. **Смена домена / репо** — задача завершает один трек перед переходом на несвязанный.
|
||
2. **Milestone-задача** — последняя в группе sub-tasks одной фичи.
|
||
3. **Тяжёлая инфра-задача** — shared checkout, migrations, deploy — где разумно остановиться и проверить состояние.
|
||
|
||
Значение: `true` (следующий трек = «см. STATUS.md») либо строка-hint с названием следующего трека. Потребитель — `using-tasks` v1.2.0+ (Task completion step 6): после 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. Сопроводительное письмо — обязательно при кросс-проектной делегации
|
||
|
||
После создания **каждая кросс-проектная делегация** дублируется письмом в
|
||
инбокс получателя (канон — `inter-session-messaging` v2: канал Mappa, адрес
|
||
из адресной книги `~/projects/.wiki/concepts/projects-address-book.md`):
|
||
|
||
```
|
||
mcp__mappa__inbox_send(
|
||
project: <адрес-получателя>, # имя папки, из адресной книги
|
||
from: <своя-папка>,
|
||
subject: "[event: created] #n slug",
|
||
body: "1-2 строки — что за задача, почему, slug; «разбери и возьми»"
|
||
)
|
||
```
|
||
|
||
(Мутация тасок гейтится лизом проекта — `task_claim_next`; доставка письма —
|
||
карв-аут, лиза не требует.)
|
||
|
||
Причина: таска на борде **не пингует живую сессию** получателя. Поллер
|
||
подхватит по `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-проекте через `mcp__projects-meta__tasks_create` (Gitea commit).
|
||
- Опционально создаёт парную review-таску (status=blocked).
|
||
|
||
## 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), не дефолт; иначе `using-tasks` рвёт сессию после каждого close.
|
||
- **Не создавать задачи из дизайна/решения без `**Спека:**`-ссылки** —
|
||
импл-агент угадывает пороги/скоуп вместо чтения дизайна.
|
||
- **Не создавать несколько тасок в один репо параллельно** — sha-lock
|
||
конфликты (PushRejected); сериализуй confirm'ы.
|
||
- **Не делегировать кросс-проектную задачу без сопроводительного письма** в
|
||
инбокс получателя (шаг 5, Mappa `inbox_send`). `tasks_create` в чужой борд
|
||
живую сессию не пингует — task без letter остаётся незамеченной до
|
||
поллера/руки.
|
||
- **Не поручать агенту создать downstream-таску для живой сессии без парного inbox-письма** (см. Step 7). `tasks_create` в чужой борд живую сессию не пингует — ТЗ обязано требовать И таску, И письмо, иначе downstream-таска висит незамеченной.
|