feat(task-format): v0.3.0 — primary mappa task.create schema, legacy STATUS.md interim (#983)
Канон создания — через mcp__mappa__task_create (per-type t:N, мутация под лизом). Legacy-блоки .tasks/STATUS.md — интерм до переключения поллера (#984).
This commit is contained in:
@@ -1,27 +1,76 @@
|
|||||||
---
|
---
|
||||||
name: task-format
|
name: task-format
|
||||||
author: ours
|
author: ours
|
||||||
version: 0.2.0
|
version: 0.3.0
|
||||||
description: >
|
description: >
|
||||||
Use when writing or editing a task block in a `.tasks/STATUS.md` board that an
|
Use when creating or editing a task so it is actually claimable and routed —
|
||||||
autonomous task-runner ("poller") will read — so the task is actually claimed,
|
not silently skipped. Primary channel: **mappa** — create via
|
||||||
routed, and reported instead of silently skipped. Covers the exact block header,
|
`mcp__mappa__task_create` (схема ниже), не руками. Legacy: пока файловый
|
||||||
the status emoji, and the `**Weight:**` / `**Notify:**` / `**Requirements:**`
|
поллер (agents-task-runner) не переключён на mappa (#984), блоки в
|
||||||
fields the poller parses. Triggers: «оформить таску для поллера», «формат таски»,
|
`.tasks/STATUS.md` обязаны совпадать со строгим форматом (шапка, поля
|
||||||
«task block format», «make a task the poller will pick up», «add Weight/Notify»,
|
Weight/Notify), иначе поллер молча пропускает. Triggers: «оформить таску для
|
||||||
poller / agent-runner not claiming a task you wrote by hand.
|
поллера», «формат таски», «task block format», «make a task the poller will
|
||||||
|
pick up», «add Weight/Notify», poller / agent-runner not claiming a task.
|
||||||
---
|
---
|
||||||
|
|
||||||
# task-format
|
# task-format
|
||||||
|
|
||||||
The autonomous poller parses `.tasks/STATUS.md` line-by-line with **strict regexes**. A block runs only if its header and fields match exactly. Get the format wrong and the poller does not error — it silently skips the block, or claims it and then parks it. This is the canonical field reference.
|
Канон создания задачи — **через тул**, не рукописным блоком. Поллер (автономный
|
||||||
|
раннер) разбирает задачи строгими правилами; формат задаёт, какая таска будет
|
||||||
|
взята, отмаршрутизирована и зарепорчена, а какая молча пропущена.
|
||||||
|
|
||||||
> Authoring a task for **another** project/agent via `mcp__projects-meta__tasks_create`? Use `delegate-task` — it drives the tool, which emits this format for you. This skill is the format itself: for **hand-edited** STATUS.md blocks and for understanding what the poller reads. For board working policy (claim/close/status), see `using-tasks`.
|
> Создаёшь задачу для **другого** проекта/агента? См. `delegate-task` — он ведёт
|
||||||
|
> через тул + письмо. Работа с бордом (claim/close/status) — `using-tasks`.
|
||||||
|
|
||||||
## Canonical block (copy this)
|
## Primary: mappa task.create
|
||||||
|
|
||||||
|
Создание задач в mappa (решение 14/15: мета в сервисе) — только через
|
||||||
|
`mcp__mappa__task_create`, никогда руками вставляй блоки. Тул сам назначает
|
||||||
|
per-type номер (`t:N`, решение 20) и пишет сущность.
|
||||||
|
|
||||||
|
```
|
||||||
|
mcp__mappa__task_create(
|
||||||
|
project: <имя проекта>, // обязателен
|
||||||
|
slug: <kebab-case>, // обязателен, латиница
|
||||||
|
title: <одна строка>, // опционально
|
||||||
|
description: <markdown>, // тело; [[refs]] → рёбра (решение 4)
|
||||||
|
status: ready | active | paused | blocked | done, // по умолчанию ready
|
||||||
|
claim_token: <токен лиза проекта> // мутация под лизом (решение 19)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Мутация под лизом (решение 19):** `task_create` требует `claim_token`
|
||||||
|
активного лиза проекта (берётся `mcp__mappa__task_claim_next`). Без лиза —
|
||||||
|
422 busy. (Карв-аут: чтения и инбокс-доставка лиза не требуют.)
|
||||||
|
|
||||||
|
**Per-type номер (решение 20):** номер — канонический машинный реф `t:N`
|
||||||
|
(см. ответы — поле `ref`). Глобальный id — internal, только для addressing
|
||||||
|
(#1037). Ссылки на задачу в тексте — `[[t:N]]`, не `#<глобальный id>`.
|
||||||
|
|
||||||
|
**Slug-правила:** короткий, lowercase, kebab-case, латиница
|
||||||
|
(`fix-nl-vds-reality-pq-dest`, не `Fix_this_TASK #1`).
|
||||||
|
|
||||||
|
## Status emoji ↔ state
|
||||||
|
|
||||||
|
| Emoji | State | Значение |
|
||||||
|
|---|---|---|
|
||||||
|
| ⚪ | `ready` | единственное состояние, которое поллер берёт |
|
||||||
|
| 🔴 | `active` | взято / в работе |
|
||||||
|
| 🟡 | `paused` | возобновляемо |
|
||||||
|
| 🔵 | `blocked` | ждёт (указать почему в description/where_stopped) |
|
||||||
|
| 🟢 | `done` | закрыто |
|
||||||
|
|
||||||
|
Не путай: 🟢 — это *done*, не «готово».
|
||||||
|
|
||||||
|
## Legacy: блок .tasks/STATUS.md (интерм до #984)
|
||||||
|
|
||||||
|
Пока файловый поллер (agents-task-runner) не переключён на mappa-лиз (#984),
|
||||||
|
блоки в `.tasks/STATUS.md`, создаваемые руками/миграцией, обязаны совпадать со
|
||||||
|
строгим форматом — иначе поллер молча пропускает или паркует. **Это
|
||||||
|
переходный канон; новые задачи создавай через task_create.**
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
## ⚪ [#1234 my-task-slug] — One-line description of the work.
|
## ⚪ [#1234 my-task-slug] — One-line description.
|
||||||
|
|
||||||
**Status:** ready
|
**Status:** ready
|
||||||
**Created:** 2026-08-23
|
**Created:** 2026-08-23
|
||||||
@@ -35,76 +84,54 @@ The autonomous poller parses `.tasks/STATUS.md` line-by-line with **strict regex
|
|||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
## The two load-bearing rules
|
Три load-bearing правила:
|
||||||
|
|
||||||
1. **Header must match exactly:** `## <emoji> [#<n> <slug>] — <description>`
|
1. **Шапка точно:** `## <emoji> [#<n> <slug>] — <description>` — h2, один emoji,
|
||||||
- `## ` (h2, two hashes) — **not** `### `, not a bullet.
|
`[#<n> <slug>]` (глобальный номер, без ведущих нулей), разделитель
|
||||||
- One status **emoji**, then `[#<n> <slug>]` in square brackets — **global task number** (`#1234`, no leading zeros) + slug — then ` — ` (space, em-dash `—`, space), then the description. A `-` hyphen or `:` will not match.
|
` — ` (пробел + em-dash + пробел). Несовпавшая шапка = задача не видна вообще.
|
||||||
- **Number is the machine key.** Global, unique across the whole federation, encodes creation order. References (`#452` in letters, blocker fields, decision trails) point at the number. The slug is the human-readable part only.
|
2. **Поля — строки `**Label:** value`.** Буллеты и проза игнорируются.
|
||||||
- Slug: short, lowercase, kebab-case, Latin.
|
3. **`**Created:** yyyy-mm-dd` обязателен** — пишется один раз при создании.
|
||||||
- A header that doesn't match is **not seen as a task at all**.
|
|
||||||
|
|
||||||
2. **Fields are `**Label:** value` lines** — bold label, colon, space, value. Bullet-list fields (`- **weight:** …`) and prose ("notify workshop when done") are **ignored** — the poller never reads them.
|
Номера legacy-блоков назначает сервер (`tasks_create` из счётчика
|
||||||
|
`OpeItcLoc03/agenda/task-counter`) — **никогда не выдумывай номер руками**.
|
||||||
|
|
||||||
3. **`**Created:** yyyy-mm-dd` is mandatory** — the creation date. Written once at task creation, never edited after.
|
### Поля, которые поллер разбирает
|
||||||
|
|
||||||
## Numbering
|
|
||||||
|
|
||||||
- **Numbers are assigned by the server** (`mcp__projects-meta__tasks_create`) from the counter in `OpeItcLoc03/agenda/task-counter` — never invent or reuse a number by hand.
|
|
||||||
- The **file name** is `yyyy-mm-dd-#####-<slug>.md` — number **5 digits with leading zeros, no `#`**: `2026-06-05-00019-fix-nl-vds-reality-pq-dest.md`. Leading zeros make folder sort = numeric up to 99999. No `#` in the filename (it would break markdown links and Gitea URLs).
|
|
||||||
- In the **header and text references** the number is written **without** leading zeros: `[#19 slug]`.
|
|
||||||
|
|
||||||
## Status emoji ↔ state
|
|
||||||
|
|
||||||
| Emoji | State | |
|
|
||||||
|---|---|---|
|
|
||||||
| ⚪ | **ready** | the only state the poller claims |
|
|
||||||
| 🔴 | active | claimed / in flight |
|
|
||||||
| 🟡 | paused | resumable |
|
|
||||||
| 🔵 | blocked | waiting on a `**Blocker:**` |
|
|
||||||
| 🟢 | done | kept until merged |
|
|
||||||
|
|
||||||
`**Status:**` mirrors the emoji in words. ⚪ → `ready`. **Do not** use 🟢 for "ready" — 🟢 is *done*.
|
|
||||||
|
|
||||||
## Fields the poller parses
|
|
||||||
|
|
||||||
| Field | Format | Meaning |
|
| Field | Format | Meaning |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `**Weight:**` | `cheap-ok` \| `needs-claude` \| `needs-human` | Routing tier. **Required for autonomous pickup** — see below. |
|
| `**Weight:**` | `cheap-ok` \| `needs-claude` \| `needs-human` | Тир маршрутизации. **Обязателен** для авто-взятия. |
|
||||||
| `**Notify:**` | `<owner>/<repo>` | Inbox target. Poller writes to that project's `.agents/inbox/` on close / park / delivery-failure. Omit → no report; the steering loop never closes. |
|
| `**Notify:**` | `<owner>/<repo>` | Инбокс-адрес для событий close/park/delivery-failure. |
|
||||||
| `**Requirements:**` | CSV, e.g. `needs-db, needs-secrets` | Hard capability gate. The agent must hold **all** listed capabilities or the task is skipped. |
|
| `**Requirements:**` | CSV (`needs-db, needs-secrets`) | Capability-гейт: агент должен держать ВСЕ. |
|
||||||
| `**Runtime allowed:**` | CSV, e.g. `claude-opus` | Runtime whitelist. If set, only a listed runtime may claim. |
|
| `**Runtime allowed:**` | CSV (`claude-opus`) | Runtime-whitelist. |
|
||||||
| `**Consult policy:**` | `auto` \| `human-only` \| `strict-human` | How a mid-run `consult` escalates. Default when absent: `human-only`. |
|
| `**Consult policy:**` | `auto` \| `human-only` \| `strict-human` | Эскалация consult; default `human-only`. |
|
||||||
| `**Blocker:**` | CSV of blocker slugs | Only on 🔵 blocked. Auto-unblock flips the task to ⚪ when every blocker is 🟢. |
|
| `**Blocker:**` | CSV blocker-slug'ов | Только на 🔵; авто-unblock при 🟢 всех. |
|
||||||
| `**Next action:** / **Where I stopped:** / **Branch:**` | free text | Core resumability fields. |
|
| `**Next action:** / **Where I stopped:** / **Branch:**` | free text | Резюмируемость. |
|
||||||
|
|
||||||
`**Owner:** / **Claim token:** / **Claim expires at:**` are the **claim stamp** — the poller writes and clears them. Never author them by hand; a stale stamp on a ⚪ task blocks the poller.
|
`**Owner:** / **Claim token:** / **Claim expires at:**` — claim-штамп, пишет и
|
||||||
|
чистит поллер. Не автори руками; залипший штамп на ⚪ блокирует поллер.
|
||||||
|
|
||||||
## Weight — the field that decides pickup
|
**Weight — поле, решающее взятие:** без `**Weight:**` поллер берёт задачу, не
|
||||||
|
находит тир и паркует в 🔵 (`no backend for weight_tier: unknown`). Обычный код
|
||||||
|
→ `needs-claude`; критикал-инфра (поллер, MCP-серверы, деплой, CI, git-хуки) →
|
||||||
|
`needs-human` (никогда не авто).
|
||||||
|
|
||||||
The poller routes each claimed task to a backend by its weight tier:
|
## Common mistakes
|
||||||
|
|
||||||
- `cheap-ok` — routine work, a cheap/weak model is fine.
|
|
||||||
- `needs-claude` — needs a capable model (refactors, anything where discipline matters, review).
|
|
||||||
- `needs-human` — **never** runs autonomously. The claim gate excludes it and the runner refuses to spawn. Use for anything touching critical infra: the poller/agent-runner itself, MCP servers, claim/close/heartbeat, deploy, CI/CD, git hooks.
|
|
||||||
|
|
||||||
**No `**Weight:**` line → no backend tier matches → the poller claims the task, finds no route, and parks it to 🔵 blocked (`no backend for weight_tier: unknown`).** So a task you want run **must** carry a Weight. If in doubt and the work is ordinary code, use `needs-claude`.
|
|
||||||
|
|
||||||
## Common mistakes (from baseline failures)
|
|
||||||
|
|
||||||
| Mistake | Fix |
|
| Mistake | Fix |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `### Title` or a `- **id:** …` bullet list | Use the exact `## <emoji> [#n slug] — desc` h2 header + `**Field:**` lines. |
|
| Рукописный блок вместо `task_create` | Создавай через тул — номер/формат серверные. |
|
||||||
| 🟢 for a ready task | 🟢 is *done*. Ready is ⚪. |
|
| `### Title` / буллеты вместо полей | `## <emoji> [#n slug] — desc` + `**Field:** value`. |
|
||||||
| Header `[slug]` without a number | Header is `[#n slug]` — the number is the machine key. |
|
| 🟢 для ready | 🟢 — done. Ready — ⚪. |
|
||||||
| `**Created:**` missing | Add `**Created:** yyyy-mm-dd` — mandatory field. |
|
| Шапка `[slug]` без номера | `[#n slug]` — номер машинный ключ. |
|
||||||
| Inventing a number by hand | Numbers come only from `tasks_create` (counter). Never invent/reuse. |
|
| Выдуманный номер | Номер — только от сервера (task_create). |
|
||||||
| File named `2026-06-05-19-slug.md` (no leading zeros) | File is `yyyy-mm-dd-#####-slug.md`, number 5 digits: `00019`. |
|
| `**Created:**` отсутствует (legacy) | Добавить — обязательное поле. |
|
||||||
| Inventing `risk: low`, `tier: L`, `priority`, `claimable-by` | The poller routes on `**Weight:**` with three fixed values only. |
|
| Ссылка `#<глобальный id>` | Ссылайся `[[t:N]]` (решение 20/#1037). |
|
||||||
| Notification written as prose / "Done-signal" | Use a real `**Notify:** <owner>/<repo>` field line. |
|
| Без `**Weight:**` (legacy) | Ставь всегда, или задача паркуется. |
|
||||||
| Omitting Weight on a task you want auto-run | Always set Weight, or the task parks. |
|
| Дефис/двоеточие вместо ` — ` в шапке | Разделитель — пробел + em-dash + пробел. |
|
||||||
| Hyphen or colon instead of ` — ` in the header | The separator is space + em-dash + space. |
|
|
||||||
|
|
||||||
## Verify
|
## Verify
|
||||||
|
|
||||||
After editing, the block is correct when: header is `## <emoji> [#n slug] — …`, the emoji matches `**Status:**`, `**Created:** yyyy-mm-dd` is present, every machine-read field is a `**Label:**` line (not a bullet), and a task meant for the poller has both `**Weight:**` (not `needs-human` unless intended) and `**Notify:**`.
|
Задача корректна, когда: создана через `task_create` (или legacy-блок: шапка
|
||||||
|
`## <emoji> [#n slug] — …`, emoji = `**Status:**`, `**Created:**` есть, поля —
|
||||||
|
`**Label:**` строки, есть `**Weight:**` и `**Notify:**`); slug kebab-case;
|
||||||
|
ссылки на неё — `[[t:N]]`.
|
||||||
|
|||||||
Reference in New Issue
Block a user