Files
skills/skills/mappa-delegation/SKILL.md

13 KiB

name, author, version, description
name author version description
mappa-delegation ours 1.3.0 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

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

Before every tasks_create call for another project or agent.

Activates: «делегировать таску», «создать задачу на агента», «поставить задачу агенту», «tasks_create для», "delegate task", "create a task for an agent".

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 <owner>/<repo> (required)
  • slug — kebab-case latin
  • Short task description (goal + acceptance criteria)
  • weightcheap-ok | needs-claude | needs-human
  • notify — commissioning project slug (who gets the inbox letter on close/park)

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.

Contract (interactive, wiki:2660). task_createcarve-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 (the cycle)

1. Pre-flight gate (6 questions to the user)

Ask before composing the task body:

  1. 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.
  2. Interns — allowed? (yes/no, per task)
  3. Auto-push — allowed? (yes/no, per task)
  4. 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.
  5. notify — who gets the completion/block report? (project slug; usually .workshop or OpeItcLoc03/workshop)
  6. 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. Compose the task body per template

Sections strictly in order:

<Goal — one or two sentences. Acceptance criteria if any.>
**Spec:** <path to the design solution or .brainstorm/…> — mandatory for tasks
from design/decision: the impl reads the design, doesn't guess

## Mandatory skills — invoke before starting work

- 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/<slug>.md
[if cross-project: - invoke `using-projects-meta` — cross-project tasks/wiki]
[contextual skills from step 1.3]

**TDD:** yes | no — <reason>
**Permissions:** interns: yes/no | auto-push: yes/no
**weight:** cheap-ok | needs-claude | needs-human
**notify:** <commissioning-project-slug>
[**allow_upgrade:** true/false]
[**session_break:** true | "<next track / hint>"]   # optional — mappa-task-work stops after close, doesn't claim the next task

When to set session_break (optional; by default DON'T set it — it marks a real boundary, not a default). Three cases:

  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.

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: if the solution splits into stages (1 → 1b → 3), create each stage as a separate task with status: blocked + blocker: <predecessor numbers> (#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).

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) — show the user the preview before the real commit.

4. Confirmation and creation

After the user's OK: tasks_create(confirm=true).

5. Covering letter — mandatory for cross-project delegation

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: <recipient address>,   # folder name, from the address book
  from:    <your folder>,
  subject: "[event: created] #n slug",
  body:    "1-2 lines — what the task is, why, slug; «sort it out and take it»"
)

(«sort it out and take it» — intentionally bilingual placeholder: the covering letter body may be written in the recipient's language (Russian for Russian-speaking projects, English otherwise). Not a trigger phrase.)


(update/close mutations — version-based (409 → retry); letter delivery —
carve-out, requires no lease.)

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).

Skip: self-assigned tasks on your own board; `target=agenda` (shared board,
no concrete recipient — steering-loop via `Notify`).

### 6. Paired review task (impl tasks only)

If the task is implementation — create the paired `<slug>-review`
(status=blocked, blocker=`#n` — the impl task number). Skip for: pointer
tasks, ops tasks, research tasks, any non-impl.

**`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` (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` (floor: review is
  discipline-critical, see What NOT to do — don't drop to cheap-ok).

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 for a LIVE session → require task + inbox letter

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=<target>, from=<yours>, subject="[event: created] #n slug", ...)`).

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.

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

- **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

- 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

- 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

- 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).