docs(skills): mappa-task-work 1.2.0→1.3.0 — English translation, bilingual triggers (task:1086)

This commit is contained in:
2026-08-25 17:42:37 +03:00
parent 0177d46101
commit 195de4b8e6

View File

@@ -1,238 +1,247 @@
--- ---
name: mappa-task-work name: mappa-task-work
author: ours author: ours
version: 1.2.0 version: 1.3.0
description: > description: >
Центральный цикл работы с тасками в Mappa: ориентация → выбор работы The central cycle of working with tasks in Mappa: orientation → work
(priority/due) → исполнение → сдача (close + review-umbrella) + selection (priority/due) → execution → handover (close + review-umbrella) +
loop-mode «поработай очередь». Борд = сущности mappa (решения 14/15/19/20); loop-mode "work the queue". Board = mappa entities (decisions 14/15/19/20);
create — карв-аут, update/close — optimistic concurrency (version+409), create — carve-out, update/close — optimistic concurrency (version+409),
owner = персистентный assignee, живость — из session владельца owner = persistent assignee, liveness — from the owner's session (interactive
(interactive contract, wiki:2660). Поглощает using-tasks + contract, wiki:2660). Absorbs using-tasks + task-format + task-loop (loop-mode
task-format + task-loop (loop-mode ВНУТРИ) + priority-due-раздел (старые INSIDE) + priority-due section (old names — trigger-synonyms).
имена — триггер-синонимы). Triggers (bilingual): «что на досках», «возьми таску», «какой статус»,
Триггеры: «что на досках», «возьми таску», «какой статус», «update status», «update status», «pause», «switch to X», «где мы остановились», "work the
«pause», «switch to X», «где мы остановились», «work the queue», «поработай queue", «поработай очередь», «прогони доску», "what's on the boards", "take
очередь», «прогони доску». Приоритет = территория человека: агенты ставят a task". Priority = the human's territory: agents set P0-P2/deadline only at
P0-P2/дедлайн только при создании, дефолт P1; просрочка → notify, без creation, default P1; overdue → notify, no auto-bump. NOT about delegation
авто-бампа. НЕ про делегирование (→ mappa-delegation), НЕ про доску-обзор (→ mappa-delegation), NOT about board overview (→ ops/using-system-snapshot).
(→ ops/using-system-snapshot).
--- ---
# mappa-task-work # mappa-task-work
Центральный цикл работы с задачами: **ориентация → выбор работы → исполнение The central cycle of working with tasks: **orientation → work selection
сдача**. Борд — сущности mappa (`type=task`, `task:N`): чтение — карв-аут; execution → handover**. Board — mappa entities (`type=task`, `task:N`): read —
**create — карв-аут без лиза; update/close — optimistic concurrency carve-out; **create — carve-out without a lease; update/close — optimistic
(version+409 → retry)**; **owner = персистентный assignee; живость таски — concurrency (version+409 → retry)**; **owner = persistent assignee; task
из session владельца** (interactive contract, wiki:2660; поллер вне mappa). liveness — from the owner's session** (interactive contract, wiki:2660; poller
Скилл = цикл, не тул: одна механика на выбор/исполнение/сдачу, плюс outside mappa). The skill is a cycle, not a tool: one mechanics for
**loop-mode** («поработай очередь») внутри — отдельный скил не создаётся. selection/execution/handover, plus **loop-mode** («поработай очередь») inside —
no separate skill is created.
> **Переходное (file channel).** Пока поллер/кэш читают файловые борды > **Transitional (file channel).** While the poller/cache reads file boards
> (`.tasks/STATUS.md`), legacy-канал живёт: блоки в файле обязаны строгому > (`.tasks/STATUS.md`), the legacy channel lives: file blocks must obey a
> формату (см. «Формат таски» ниже), мутации — через `mcp__projects-meta__tasks_*` > strict format (see "Task format" below), mutations — via
> (Gitea-коммиты). Новые таски — через `mcp__mappa__task_create`. Не смешивай. > `mcp__projects-meta__tasks_*` (Gitea commits). New tasks — via
> `mcp__mappa__task_create`. Don't mix.
## Когда использовать ## When to use
- «что на досках», «возьми таску», «какой статус», «update status», «pause», «switch to X», «где мы остановились». - «что на досках», «возьми таску», «какой статус», «update status», «pause», «switch to X», «где мы остановились», "what's on the boards", "take a task".
- «work the queue», «поработай очередь», «прогони доску» → **loop-mode**. - "work the queue", «поработай очередь», «прогони доску» → **loop-mode**.
- Смена задачи / пауза / конец сессии — держать борд консистентным. - Task switch / pause / session end — keep the board consistent.
**НЕ для:** делегирования другому агенту/проекту (→ `mappa-delegation`), **NOT for:** delegating to another agent/project (→ `mappa-delegation`),
промоушена (→ `mappa-brainstorm-promote`), инфра-диагностики (→ `using-vds-ops`), promotion (→ `mappa-brainstorm-promote`), infra diagnosis (→ `using-vds-ops`),
кросс-проектного обзора (→ `using-system-snapshot`). cross-project overview (→ `using-system-snapshot`).
## MCP-поверхность ## MCP surface
| Операция | Тул | Примечание | | Operation | Tool | Note |
|---|---|---| |---|---|---|
| Взять следующую ready-таску | `mcp__mappa__task_update(project, id, owner=<своя>, status=active…, version)` | **conditional update**: status→active, owner=X, version+409 (кто первый с верной version — тот и взял) | | Take the next ready task | `mcp__mappa__task_update(project, id, owner=<yours>, status=active…, version)` | **conditional update**: status→active, owner=X, version+409 (whoever is first with the right version — takes it) |
| Создать таску | `mcp__mappa__task_create(project, slug, title?, description?, status?, priority?, due?)` | **карв-аут без лиза**; per-type номер (решение 20) | | Create a task | `mcp__mappa__task_create(project, slug, title?, description?, status?, priority?, due?)` | **carve-out without a lease**; per-type number (decision 20) |
| Закрыть таску | `mcp__mappa__task_close(project, id, version)` | **version-based**: конфликт → 409 → retry со свежей version из task_get | | Close a task | `mcp__mappa__task_close(project, id, version)` | **version-based**: conflict → 409 → retry with the fresh version from task_get |
| Обновить таску | `mcp__mappa__task_update(project, id, parent?, owner?, status?, reason?, version)` | version-based; 409 → retry | | Update a task | `mcp__mappa__task_update(project, id, parent?, owner?, status?, reason?, version)` | version-based; 409 → retry |
| Прочитать таску | `mcp__mappa__entity_get(id)` | id internal из search | | Read a task | `mcp__mappa__entity_get(id)` | internal id from search |
| Список борда | `mcp__mappa__entity_search(q, type='task', project=<имя>, limit)` | все статусы | | Board list | `mcp__mappa__entity_search(q, type='task', project=<name>, limit)` | all statuses |
| Дерево parent_of | `mcp__mappa__graph_tree(root, depth?, fields?, limit?)` | зонтики/иерархия | | parent_of tree | `mcp__mappa__graph_tree(root, depth?, fields?, limit?)` | umbrellas/hierarchy |
| Связанные сущности | `mcp__mappa__graph_neighbors/backlinks(id)` | рефы к таске | | Related entities | `mcp__mappa__graph_neighbors/backlinks(id)` | refs to the task |
| Просрочка | `mcp__mappa__admin_overdue_scan(project?)` | P2-джоба: notify в инбокс, без мутаций | | Overdue | `mcp__mappa__admin_overdue_scan(project?)` | P2 job: notify to inbox, no mutations |
| Живость владельца | `mcp__mappa__session_list(project, stale_minutes?)` | сессия владельца жива/стала stale → таска active or not | | Owner liveness | `mcp__mappa__session_list(project, stale_minutes?)` | owner's session alive/stale → task active or not |
| Уведомление при закрытии | `mcp__mappa__inbox_send(project=<notify>, from=<своя>, subject, body)` | письмо комиссионеру | | Close notification | `mcp__mappa__inbox_send(project=<notify>, from=<yours>, subject, body)` | letter to the commissioner |
**Owner = персистентный assignee; живость — из session (interactive contract, **Owner = persistent assignee; liveness — from the session (interactive
wiki:2660).** Нет TTL/claim/таймера на таске: «взял таску» = conditional contract, wiki:2660).** No TTL/claim/timer on the task: "took a task" =
update (`status→active, owner=X` + version, 409 при конфликте — кто первый, conditional update (`status→active, owner=X` + version, 409 on conflict —
тот и взял). Живость владельца — сессия: таска с owner=X активна, пока сессия whoever is first takes it). Owner liveness — the session: a task with owner=X
X жива (end-state≠clean, не stale; `session_list(project)`); краш = stale is active while session X is alive (end-state≠clean, not stale;
решает человек/оркестратор (поллер вне mappa, работает на файловых досках `session_list(project)`); crash = stale → the human/orchestrator decides
projects-meta). Write-пути (create/update/close) лизов/claim не требуют — (poller outside mappa, works on projects-meta file boards). Write paths
только version на update/close (409 при конфликте). (create/update/close) require no leases/claims — only version on update/close
(409 on conflict).
**Рефы и id (#1037/#1028).** Таски наружу несут `ref: "t:N"` полным именем **Refs and ids (#1037/#1028).** Tasks carry `ref: "t:N"` by full name as the
первым полем (`task:N`, конвенция #1028), `num` следом, глобальный `id` first field (`task:N`, convention #1028), `num` next, the global `id`
internal (последним, для addressing в тулах). Ссылайся на таску internal (last, for addressing in tools). Reference a task as
`[[task:N]]`/`task:N` в прозе (слаг/имя первым, реф как якорь: «таска `[[task:N]]`/`task:N` in prose (slug/name first, ref as anchor: "the task
`mappa-task-work` (task:1062)»), никогда `#<глобальный id>`. `mappa-task-work` (task:1062)"), never `#<global id>`.
## Статусы (эмодзи для презентации) ## Statuses (emojis for presentation)
| Эмодзи | Статус | Значение | | Emoji | Status | Meaning |
|---|---|---| |---|---|---|
| ⚪ | `ready` | не начата, полностью определена | | ⚪ | `ready` | not started, fully defined |
| 🔴 | `active` | в работе (обычно одна) | | 🔴 | `active` | in progress (usually one) |
| 🟡 | `paused` | в процессе, возобновляема | | 🟡 | `paused` | in progress, resumable |
| 🔵 | `blocked` | ждёт внешнего входа | | 🔵 | `blocked` | waiting on external input |
| 🟢 | `done` | закрыта | | 🟢 | `done` | closed |
Не путай: 🟢 — *done*, не «готово». Ready ⚪. Don't confuse: 🟢 — *done*, not "ready". Ready is ⚪.
--- ---
## Цикл ## The cycle
### Фаза 0 — Ориентация ### Phase 0 — Orientation
1. **Инбокс-свип**`mcp__mappa__inbox_monitor(project=<имя>)`: непрочитанные 1. **Inbox sweep**`mcp__mappa__inbox_monitor(project=<name>)`: unread
письма могут менять план. Обработай каждое по `mappa-messaging`. letters may change the plan. Handle each per `mappa-messaging`.
2. **Борд**`entity_search(q, type='task', project=<имя>, limit=50)`: отсортируй 2. **Board**`entity_search(q, type='task', project=<name>, limit=50)`: sort
по статусу (🔴 → 🟡 → ⚪), по одной строке на таску, цитируй slug. by status (🔴 → 🟡 → ⚪), one line per task, quote the slug.
3. Если user назвал таску`entity_get(id)` по её рефу/номеру. 3. If the user named a task`entity_get(id)` by its ref/number.
4. Подтверди одним предложением: «Мы в середине X, следующий шаг — Y». 4. Confirm in one sentence: "We're in the middle of X, next step — Y".
5. Спроси, верен ли план, перед действиями. 5. Ask whether the plan is right before acting.
### Фаза 1 — Выбор работы (priority/due) ### Phase 1 — Work selection (priority/due)
1. **Выбор таски — из списка борда** (`entity_search(q, type='task', project)`): 1. **Task selection — from the board list** (`entity_search(q, type='task', project)`):
порядок — **P0-пул первый, внутри по дедлайну (просроченные первыми), order — **P0 pool first, within it by deadline (overdue first),
потом P1, потом P2**; отсутствующий priority = P1 (task-priority-due). then P1, then P2**; missing priority = P1 (task-priority-due).
«Взять таску» = `task_update(project, id, owner=<своя>, status='active', "Take a task" = `task_update(project, id, owner=<yours>, status='active',
version)` — conditional update: status→active, owner=X, version+409; кто version)` — conditional update: status→active, owner=X, version+409;
первый с верной version — тот и взял (interactive contract, wiki:2660). whoever is first with the right version takes it (interactive contract,
`owner` = `<machine>:<runtime>:<session>`. wiki:2660). `owner` = `<machine>:<runtime>:<session>`.
2. **Локально-первая рекомендация** — борд cwd первым; кросс-проект — футонота 2. **Local-first recommendation** — cwd board first; cross-project — a footnote
(`Cross-project: N 🔴 active — см. tasks_aggregate`) только если N>0 и в cwd (`Cross-project: N 🔴 active — see tasks_aggregate`) only if N>0 and there's
нет активной 🔴. Кросс-проектные ургенты — информация, не драйвер «что делать здесь». no active 🔴 in cwd. Cross-project urgencies are information, not a driver
3. **Priority/Due — территория человека (раздел task-priority-due):** for "what to do here".
- Агент ставит `priority`/`due` **только при создании** таски (явные параметры 3. **Priority/Due — the human's territory (task-priority-due section):**
или строки `**Priority:** P0|P1|P2` / `**Due:** yyyy-mm-dd` в description). - An agent sets `priority`/`due` **only at task creation** (explicit
Отсутствует → дефолт P1, без дедлайна. parameters or `**Priority:** P0|P1|P2` / `**Due:** yyyy-mm-dd` lines in
- **После создания агент не меняет** приоритет/дедлайн — прецедент человека the description). Absent → default P1, no deadline.
структурный (update агентами отклоняется сервером). Обнаружил, что таска - **After creation an agent doesn't change** priority/deadline — the
на самом деле P0 → паркуй вопрос человеку, не бампай сам. human's precedent is structural (agent updates are rejected by the
- **Просрочка:** due < today при ready/active → `admin_overdue_scan` уведомляет server). If you discover the task is actually P0 → park the question to
в инбокс **однократно, без мутаций** — никакого авто-бампа/авто-смены приоритета. the human, don't bump it yourself.
- **Overdue:** due < today with ready/active → `admin_overdue_scan`
notifies the inbox **once, without mutations** — no auto-bump/auto-priority
change.
### Фаза 2 — Исполнение ### Phase 2 — Execution
- **Одна активная таска** 🔴 на проект. Не параллель. - **One active task** 🔴 per project. No parallelism.
- Читай description + per-task файл (`<slug>.md`, где есть) до старта. - Read description + per-task file (`<slug>.md`, where present) before starting.
- Живость — из сессии владельца (`session_list(project)`), не таймер; долгие - Liveness — from the owner's session (`session_list(project)`), not a timer;
таски heartbeat не требуют (interactive contract, wiki:2660). long tasks need no heartbeat (interactive contract, wiki:2660).
- **`session_break` gate** (из task-loop): если в description таски есть маркер - **`session_break` gate** (from task-loop): if the task description has the
`session_break` — после close НЕ клейми следующую: печатай `session_break` marker — after close DON'T claim the next one: print
`🔚 SESSION BOUNDARY …` и останавливайся (домен-свитч / milestone / тяжёлая инфра). `🔚 SESSION BOUNDARY …` and stop (domain-switch / milestone / heavy infra).
### Фаза 3 — Сдача (close + review-umbrella) ### Phase 3 — Handover (close + review-umbrella)
1. **Pre-close coverage check.** Собери acceptance criteria из description. Для 1. **Pre-close coverage check.** Collect acceptance criteria from the
каждого — evidence: тест в диффе, артефакт, ссылка на дизайн. Нет evidence на description. For each — evidence: a test in the diff, an artifact, a design
критерий → спроси user'а «закрывать или подождать coverage'а». reference. No evidence for a criterion → ask the user "close or wait for
2. Resolve/drop открытые вопросы. coverage".
3. `task_close(project, id, version)` → статус `done`. `version` 2. Resolve/drop open questions.
свежая из `entity_get(id)`/`task_get(id)`; конфликт (409) → re-GET → retry. 3. `task_close(project, id, version)` → status `done`. `version` — fresh from
4. **Notify-письмо (кросс-проектные таски).** Если таска пришла из другого `entity_get(id)`/`task_get(id)`; conflict (409) → re-GET → retry.
проекта (в description/meta есть `from:`/`notify:`) — `inbox_send` 4. **Notify letter (cross-project tasks).** If the task came from another
комиссионеру: `project=<notify>`, `subject="[event: closed] <slug>"`, project (there's `from:`/`notify:` in description/meta) — `inbox_send` to
body = итог (сделано, acceptance, ссылки). Живая сессия пишет сама. the commissioner: `project=<notify>`, `subject="[event: closed] <slug>"`,
Таска 🟢 ≠ комиссионер узнал. body = the outcome (done, acceptance, references). A live session writes it
5. **Review-umbrella для impl-тасок** (канон `mappa-delegation`): если таска itself. Task 🟢 ≠ commissioner learned.
имплементационная и закрыта — парная `<slug>-review` уже должна быть 5. **Review-umbrella for impl tasks** (canon `mappa-delegation`): if the task
создана при постановке (status=blocked, blocker=impl#); закрытие impl is implementation and closed — the paired `<slug>-review` should already
разблокирует ревью. Не создавай review сам, если её не было — это работа have been created at assignment (status=blocked, blocker=impl#); closing the
постановщика; упомяни в close-note. impl unblocks the review. Don't create a review yourself if it didn't exist
6. Дополни summary-строку в handoff/вики при наличии. — that's the assigner's job; mention it in the close-note.
6. Add a summary line to the handoff/wiki if present.
### Пауза / переключение / конец сессии ### Pause / switch / session end
1. Текущая 🔴 → `task_close` если завершена (см. Фазу 3), иначе пометь 1. Current 🔴 → `task_close` if finished (see Phase 3), otherwise mark
`status=paused` (owner остаётся; «where stopped»в description или handoff). `status=paused` (owner stays; "where stopped"in the description or handoff).
2. **Инбокс-свип** на границе тасок (`inbox_monitor`). 2. **Inbox sweep** at the task boundary (`inbox_monitor`).
3. Возьми следующую: `task_update(owner, status='active', version)`прежняя 3. Take the next one: `task_update(owner, status='active', version)`the
остаётся 🟡. previous stays 🟡.
4. Подтверди ориентацию перед стартом. 4. Confirm the orientation before starting.
> **Never lose Where I stopped** — критичное поле: в description (последний > **Never lose Where I stopped** — critical field: in the description (last
> абзац) или в handoff-сущности (`mappa-closing-ritual`). Перед концом сессии > paragraph) or in the handoff entity (`mappa-closing-ritual`). Before the end
> обязательно запиши handoff. > of the session, definitely write the handoff.
--- ---
## Loop-mode — «поработай очередь» ## Loop-mode — «поработай очередь»
Один триггер-сёрфейс: «поработай очередь» / «work the queue» / «прогони доску» One trigger surface: «поработай очередь» / "work the queue" / «прогони доску»
этот режим. Work the board **в этой сессии**: взять → работа → close → взять, this mode. Work the board **in this session**: take → work → close → take,
пока очередь не пуста или user не сказал стоп. **Интерактивный цикл, не демон.** until the queue is empty or the user said stop. **Interactive cycle, not a daemon.**
``` ```
task_update(owner, status=active, version) → 409? re-GET → retry → пусто? → STOP «борд пуст» task_update(owner, status=active, version) → 409? re-GET → retry → empty? → STOP "board is empty"
таска task
работа в этой сессии (read description + <slug>.md) work in this session (read description + <slug>.md)
завершена? нет → park: blocked (внешний) | paused (возобновляемо) → следующая finished? no → park: blocked (external) | paused (resumable) → next
да yes
consult_policy: human-only/strict-human → STOP перед close/commit, спросить user consult_policy: human-only/strict-human → STOP before close/commit, ask the user
↓ auto ↓ auto
pre-close coverage check → task_close pre-close coverage check → task_close
session_break на таске? → да: печатай 🔚 SESSION BOUNDARY, STOP session_break on the task? → yes: print 🔚 SESSION BOUNDARY, STOP
нет no
следующая next
``` ```
- **Пустая очередь — естественный стоп, не wait-loop.** Нет `CronCreate`, нет - **An empty queue is a natural stop, not a wait-loop.** No `CronCreate`, no
спавна субагента, нет коротких поллеров — это работа отдельного поллера. subagent spawn, no short pollers — that's the work of a separate poller.
Длинный watch («работай пока не скажу стоп» + явно «продолжай проверять») — Long watch ("keep working until I say stop" + explicit "keep checking") —
только один `ScheduleWakeup` с интервалом ≥1200s, никогда `CronCreate`. only one `ScheduleWakeup` with an interval ≥1200s, never `CronCreate`.
- **Не завершаемая таска:** внешний блокер`status=blocked` + blocker - **Non-finishable task:** external blocker`status=blocked` + blocker
(конкретный факт + что нужно); прервал ты (бюджет/стоп) → `status=paused` + (concrete fact + what's needed); you interrupted (budget/stop) →
where_stopped. Одна упавшая таска не останавливает цикл — паркуй и дальше. `status=paused` + where_stopped. One fallen task doesn't stop the cycle —
- **Heartbeat не нужен** — живость владельца из session (wiki:2660); долгая park and continue.
таска с живой сессией не «протухает». - **No heartbeat needed** — owner liveness from the session (wiki:2660); a
- **Consult-гейт:** `auto` → автопилот до close; `human-only`/`strict-human` long task with a live session doesn't "expire".
работай, затем **STOP перед close/commit** и спроси user. Push никогда не - **Consult gate:** `auto` → autopilot up to close; `human-only`/`strict-human`
автоматический (project-discipline Rule 4: commit freely, push по явному → work, then **STOP before close/commit** and ask the user. Push is never
гранту). automatic (project-discipline Rule 4: commit freely, push on explicit grant).
--- ---
## Формат таски (из task-format) ## Task format (from task-format)
### Primary: mappa task_create ### Primary: mappa task_create
Создание задач — **через тул, не руками** (решение 20): карв-аут, лиз/claim Task creation — **via the tool, not by hand** (decision 20): carve-out, no
для create НЕ нужен (wiki:2660). Номер `task:N` назначает сервер — не выдумывай. lease/claim needed for create (wiki:2660). The number `task:N` is assigned by
the server — don't invent it.
``` ```
mcp__mappa__task_create( mcp__mappa__task_create(
project: <имя проекта>, // обязателен project: <project name>, // required
slug: <kebab-case>, // обязателен, латиница slug: <kebab-case>, // required, latin
title: <одна строка>, // опционально title: <one line>, // optional
description: <markdown>, // тело; [[refs]] → рёбра (решение 4) description: <markdown>, // body; [[refs]] → edges (decision 4)
status: ready | active | paused | blocked | done, // по умолчанию ready status: ready | active | paused | blocked | done, // default ready
priority: P0 | P1 | P2, // только при создании; отсутствует → P1 priority: P0 | P1 | P2, // only at creation; absent → P1
due: yyyy-mm-dd // только при создании; отсутствует = нет due: yyyy-mm-dd // only at creation; absent = none
) )
``` ```
Slug-правила: короткий, lowercase, kebab-case, латиница. Description — markdown, Slug rules: short, lowercase, kebab-case, latin. Description — markdown,
`[[refs]]` на связанное. Priority/Due — при создании ИЛИ строками в description `[[refs]]` to related. Priority/Due — at creation OR as lines in the
(`**Priority:** P0|P1|P2`, `**Due:** yyyy-mm-dd`; явные параметры переопределяют). description (`**Priority:** P0|P1|P2`, `**Due:** yyyy-mm-dd`; explicit
parameters override).
### Legacy: блок .tasks/STATUS.md (интерм до флипа поллера) ### Legacy: .tasks/STATUS.md block (interim until the poller flips)
Пока файловый поллер не переключён на mappa (#984), блоки в `.tasks/STATUS.md` While the file poller is not switched to mappa (#984), blocks in
обязаны строгому формату — иначе поллер молча пропускает: `.tasks/STATUS.md` must obey a strict format — otherwise the poller silently
skips:
```markdown ```markdown
## ⚪ [#1234 my-task-slug] — One-line description. ## ⚪ [#1234 my-task-slug] — One-line description.
@@ -249,65 +258,68 @@ Slug-правила: короткий, lowercase, kebab-case, латиница.
--- ---
``` ```
Три load-bearing правила: **(1)** шапка точно `## <emoji> [#<n> <slug>] — <desc>` Three load-bearing rules: **(1)** the header is exactly `## <emoji> [#<n>
(h2, один emoji, `[#<n> <slug>]`, разделитель ` — `); **(2)** поля — строки <slug>] — <desc>` (h2, one emoji, `[#<n> <slug>]`, separator ` — `); **(2)**
`**Label:** value`, буллеты игнорируются; **(3)** `**Created:**` обязателен. fields are `**Label:** value` lines, bullets are ignored; **(3)**
`**Created:**` is mandatory.
Поля, которые разбирает поллер: `**Weight:**` (cheap-ok | needs-claude | Fields the poller parses: `**Weight:**` (cheap-ok | needs-claude |
needs-human — **обязателен** для авто-взятия), `**Notify:**` (<owner>/<repo>), needs-human — **mandatory** for auto-claim), `**Notify:**` (<owner>/<repo>),
`**Requirements:**`, `**Runtime allowed:**`, `**Consult policy:**`, `**Blocker:**` `**Requirements:**`, `**Runtime allowed:**`, `**Consult policy:**`,
(только на 🔵), `**Priority:**`/`**Due:**` (как выше). `**Owner:**/`**Claim `**Blocker:**` (only on 🔵), `**Priority:**`/`**Due:**` (as above).
token:**/`**Claim expires at:**` — claim-штамп, пишет и чистит поллер; залипший `**Owner:**/`**Claim token:**/`**Claim expires at:**` — claim stamp, written
штамп на ⚪ блокирует поллер. and cleared by the poller; a stuck stamp on ⚪ blocks the poller.
**Weight — поле, решающее взятие:** без `**Weight:**` поллер паркует в 🔵 **Weight — the field that decides the take:** without `**Weight:**` the poller
(`no backend for weight_tier: unknown`). Обычный код → `needs-claude`; parks to 🔵 (`no backend for weight_tier: unknown`). Ordinary code →
критикал-инфра (поллер, MCP-серверы, деплой, CI, git-хуки) → `needs-human`. `needs-claude`; critical infra (poller, MCP servers, deploy, CI, git hooks) →
`needs-human`.
--- ---
## Failure modes ## Failure modes
- **version conflict** на update/close → version устарела; re-GET свежую version, - **version conflict** on update/close → version is stale; re-GET the fresh
retry. Не «решай конфликт» перезаписью без version (last-write-wins). version, retry. Don't "resolve the conflict" by overwriting without version
- **task_close на незавершённую** → никогда. Park (blocked/paused). (last-write-wins).
- **owner на таске без живой сессии** → таска формально active, но владелец - **task_close on an unfinished task** → never. Park (blocked/paused).
stale; спроси человека (адvisory, не замок). - **owner on a task without a live session** → the task is formally active but
- **notify не указан (legacy)** → без него boss не узнает о завершении. the owner is stale; ask the human (advisory, not a lock).
- **weight не указан (legacy)** → поллер паркует (no backend for weight_tier). - **notify not specified (legacy)** → without it the boss won't learn about completion.
- **update Priority/Due после создания** → сервер отклоняет; паркуй вопрос - **weight not specified (legacy)** → the poller parks (no backend for weight_tier).
человеку, не бампай сам. - **update Priority/Due after creation** → the server rejects; park the
question to the human, don't bump yourself.
## What NOT to do ## What NOT to do
- **Не выдумывай номера** — `task:N` назначает сервер (решение 20). - **Don't invent numbers** — `task:N` is assigned by the server (decision 20).
- **Version-дисциплина:** update/close — всегда с version (409 при конфликте - **Version discipline:** update/close — always with version (409 on conflict
re-GET → retry). Create — карв-аут без лиза (wiki:2660). re-GET → retry). Create — carve-out without a lease (wiki:2660).
- **Одна активная таска** — только одна 🔴 на проект. - **One active task** — only one 🔴 per project.
- **Never close без coverage check** — evidence на каждый acceptance criterion. - **Never close without a coverage check** — evidence for every acceptance criterion.
- **Не закрывай незавершённое** — park, не close. - **Don't close unfinished work** — park, not close.
- **Не бампай priority/due после создания** — территория человека. - **Don't bump priority/due after creation** — the human's territory.
- **Не «решай» задачи письмом/в чате** — борд — единственный источник правды - **Don't "settle" tasks by letter/in chat** — the board is the only source of
(канон mappa-messaging: «если это не на доске — это не задача»). truth (mappa-messaging canon: "if it's not on the board — it's not a task").
- **Не полли пустую очередь** — пусто = стоп и отчёт; без демона/CronCreate. - **Don't poll an empty queue** — empty = stop and report; no daemon/CronCreate.
- **Не автопилоть human-only/strict-human** через close/commit; push — только по гранту. - **Don't autopilot human-only/strict-human** through close/commit; push — only on grant.
- **Не батчи tasks_create в один репо** — sha-lock конфликты; сериализуй. - **Don't batch tasks_create into one repo** — sha-lock conflicts; serialize.
## Red flags — STOP ## Red flags — STOP
- «Поставлю таймер проверять новые таски» → нет. Стоп на пустой очереди. - "I'll set a timer to check for new tasks" → no. Stop on an empty queue.
- «Спавну фонового воркера гнать доску» → нет. Один цикл, эта сессия. - "I'll spawn a background worker to run the board" → no. One cycle, this session.
- «Таска не готова, но закрою и отмечу» → никогда. Park. - "The task isn't ready, but I'll close and mark it" → never. Park.
- «Приоритет у таски явно P0, сам бампну» → нет. Вопрос человеку. - "The task is clearly P0, I'll bump it myself" → no. Ask the human.
--- ---
## Reference ## Reference
- Делегирование (постановка на агентов): `mappa-delegation`. - Delegation (assigning to agents): `mappa-delegation`.
- Почта (covering-письма, notify): `mappa-messaging`. - Mail (covering letters, notify): `mappa-messaging`.
- Знание (wiki-ингест после закрытия): `mappa-knowledge`. - Knowledge (wiki-ingest after closing): `mappa-knowledge`.
- Финиш сессии (handoff write): `mappa-closing-ritual`. - Session finish (handoff write): `mappa-closing-ritual`.
- Старт сессии (pull/handoff/inbox/snapshot): `mappa-session-orient`. - Session start (pull/handoff/inbox/snapshot): `mappa-session-orient`.
- Промоушен: `mappa-brainstorm-promote` (review-umbrella для промоушенов). - Promotion: `mappa-brainstorm-promote` (review-umbrella for promotions).
- Кросс-проектный обзор: `using-system-snapshot` (liveness) / `mcp__projects-meta__tasks_aggregate`. - Cross-project overview: `using-system-snapshot` (liveness) / `mcp__projects-meta__tasks_aggregate`.