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_createwithtarget=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)
weight—cheap-ok | needs-claude | needs-humannotify— 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_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 (the cycle)
1. Pre-flight gate (6 questions to the user)
Ask before composing the task body:
- 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.
- If yes → force
- Interns — allowed? (yes/no, per task)
- Auto-push — allowed? (yes/no, per task)
- Contextual skills beyond defaults? — propose per task content (e.g.
claude-apifor Anthropic SDK work,frontend-designfor UI,using-internsif interns are allowed); the user approves. - notify — who gets the completion/block report? (project slug; usually
.workshoporOpeItcLoc03/workshop) - Session-break after this task? — is a session break needed after it
closes (domain-switch, milestone, heavy infra)?
- If yes → set
session_breakin the task body (see template):trueor a string-hint with the next track's name.mappa-task-workwill 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).
- If yes → set
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:
- Domain / repo switch — the task finishes one track before moving to an unrelated one.
- Milestone task — the last in a group of sub-tasks of one feature.
- 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»"
)
(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→ reviewneeds-human(a critical-infra change cannot be reviewed by a weak tier — the review inherits the impl's strictness). - impl
needs-claude→ reviewneeds-claude. - impl
cheap-ok→ reviewneeds-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 "invoketdd-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, floorneeds-claude(see Step 6). - Don't assign
weight: cheap-okwhere discipline is critical (review, security, schema migration) — weak models may ignore invoke instructions. - Don't assign
weight: needs-claudeorcheap-okto tasks changing critical infrastructure (poller, MCP servers, deploy, CI/CD) — onlyneeds-human. - Don't set
session_breakroutinely on every task — it marks a real boundary (domain-switch / milestone / heavy infra), not a default; otherwisemappa-task-workbreaks 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_createinto 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_createinto 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).