From 525a10048b0250af14382ed905f175a6c79a8084 Mon Sep 17 00:00:00 2001 From: vitya Date: Mon, 24 Aug 2026 22:48:59 +0300 Subject: [PATCH] =?UTF-8?q?feat(mappa-task-work):=20merge=20using-tasks=20?= =?UTF-8?q?+=20task-format=20+=20task-loop=20+=20priority-due=20=E2=86=92?= =?UTF-8?q?=20mappa-task-work=20v1.0.0=20(central=20cycle,=20loop-mode=20i?= =?UTF-8?q?nside,=20priority/due=20section,=20old=20names=20=3D=20trigger?= =?UTF-8?q?=20synonyms)=20[skip-tdd:=20visual]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .tasks/2026-08-24-01062-mappa-task-work.md | 11 + dist/mappa-task-work.skill | Bin 0 -> 7765 bytes dist/task-format.skill | Bin 4276 -> 0 bytes dist/task-loop.skill | Bin 3786 -> 0 bytes dist/using-tasks.skill | Bin 7259 -> 0 bytes skills/mappa-task-work/SKILL.md | 296 +++++++++++++++++++++ skills/task-format/SKILL.md | 149 ----------- skills/task-loop/SKILL.md | 118 -------- skills/using-tasks/README.md | 169 ------------ skills/using-tasks/SKILL.md | 138 ---------- 10 files changed, 307 insertions(+), 574 deletions(-) create mode 100644 dist/mappa-task-work.skill delete mode 100644 dist/task-format.skill delete mode 100644 dist/task-loop.skill delete mode 100644 dist/using-tasks.skill create mode 100644 skills/mappa-task-work/SKILL.md delete mode 100644 skills/task-format/SKILL.md delete mode 100644 skills/task-loop/SKILL.md delete mode 100644 skills/using-tasks/README.md delete mode 100644 skills/using-tasks/SKILL.md diff --git a/.tasks/2026-08-24-01062-mappa-task-work.md b/.tasks/2026-08-24-01062-mappa-task-work.md index f5c7dde..b22f4c6 100644 --- a/.tasks/2026-08-24-01062-mappa-task-work.md +++ b/.tasks/2026-08-24-01062-mappa-task-work.md @@ -17,4 +17,15 @@ Rewrite using-tasks + task-format + task-loop + priority-due → **mappa-task-wo ## Completed steps +- [x] skills/mappa-task-work/SKILL.md v1.0.0 — центральный цикл: ориентация → выбор работы (claim, priority/due) → исполнение → сдача (close + review-umbrella) + пауза/переключение +- [x] Loop-mode ВНУТРИ (вариант A, отдельный скил не создаётся): «поработай очередь»/«work the queue» → цикл claim→work→close→claim; пустая очередь = стоп, без демона/CronCreate; session_break gate; consult gate (human-only/strict-human → STOP перед close/commit) +- [x] Priority/Due-раздел: приоритет = территория человека, агент ставит только при создании, дефолт P1, просрочка → admin_overdue_scan notify однократно, без авто-бампа +- [x] Формат таски (из task-format): mappa task_create схема (priority/due при создании) + legacy STATUS.md блок (переходный, Weight/Notify обязательны) +- [x] Поглощены: using-tasks (борд/лиз/close/notify/рефы [[task:N]]), task-format (формат), task-loop (loop-mode), task-priority-due (раздел). Старые имена — триггер-синонимы в description +- [x] lint clean (65 skills, 0 violations); build.sh → dist/mappa-task-work.skill (старые .skill удалены); install.sh → dual; старые удалены из живых диров +- [x] GREEN micro-test: свежий pi -p на «поработай очередь» → активация mappa-task-work, loop-mode, стоп-гейты, пустая очередь = стоп без поллинга + ## Notes + +- RED-базис: контент унаследован из трёх скилов (все прошли ревью/smoke); дельта = слияние + цикл-фрейминг + priority/due раздел. Полный behavioral smoke (вкл. loop-mode, session-break, empty-stop) — за #1065. +- Убраны: task-loop ссылки на projects-meta claim (primary — mappa task_claim_next; file channel — переходный, описан в секции legacy). diff --git a/dist/mappa-task-work.skill b/dist/mappa-task-work.skill new file mode 100644 index 0000000000000000000000000000000000000000..c3c5b6edb50ed9ca683b40e83915de048df2a884 GIT binary patch literal 7765 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 UjPk!R`2VEv-+uZJ9>c-?4@r44rT_o{ literal 0 HcmV?d00001 diff --git a/dist/task-format.skill b/dist/task-format.skill deleted file mode 100644 index c0a732f06d160b480275e69296789458e9f52acc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4276 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 diff --git a/skills/mappa-task-work/SKILL.md b/skills/mappa-task-work/SKILL.md new file mode 100644 index 0000000..174574a --- /dev/null +++ b/skills/mappa-task-work/SKILL.md @@ -0,0 +1,296 @@ +--- +name: mappa-task-work +author: ours +version: 1.0.0 +description: > + Центральный цикл работы с тасками в Mappa: ориентация → выбор работы + (claim, priority/due) → исполнение → сдача (close + review-umbrella) + + loop-mode «поработай очередь». Борд = сущности mappa (решения 14/15/19/20); + мутации под лизом. Поглощает using-tasks + task-format + task-loop + (loop-mode ВНУТРИ) + priority-due-раздел (старые имена — триггер-синонимы). + Триггеры: «что на досках», «возьми таску», «какой статус», «update status», + «pause», «switch to X», «где мы остановились», «work the queue», «поработай + очередь», «прогони доску». Приоритет = территория человека: агенты ставят + P0-P2/дедлайн только при создании, дефолт P1; просрочка → notify, без + авто-бампа. НЕ про делегирование (→ mappa-delegation), НЕ про доску-обзор + (→ ops/using-system-snapshot). +--- + +# mappa-task-work + +Центральный цикл работы с задачами: **ориентация → выбор работы → исполнение → +сдача**. Борд — сущности mappa (`type=task`, `t:N`): чтение — карв-аут лиза, +**любая мутация — под лизом проекта** (решение 19). Скилл = цикл, не тул: +одна механика на выбор/исполнение/сдачу, плюс **loop-mode** («поработай +очередь») внутри — отдельный скил не создаётся. + +> **Переходное (file channel).** Пока поллер/кэш читают файловые борды +> (`.tasks/STATUS.md`), legacy-канал живёт: блоки в файле обязаны строгому +> формату (см. «Формат таски» ниже), мутации — через `mcp__projects-meta__tasks_*` +> (Gitea-коммиты). Новые таски — через `mcp__mappa__task_create`. Не смешивай. + +## Когда использовать + +- «что на досках», «возьми таску», «какой статус», «update status», «pause», «switch to X», «где мы остановились». +- «work the queue», «поработай очередь», «прогони доску» → **loop-mode**. +- Смена задачи / пауза / конец сессии — держать борд консистентным. + +**НЕ для:** делегирования другому агенту/проекту (→ `mappa-delegation`), +промоушена (→ `mappa-brainstorm-promote`), инфра-диагностики (→ `using-vds-ops`), +кросс-проектного обзора (→ `using-system-snapshot`). + +## MCP-поверхность + +| Операция | Тул | Примечание | +|---|---|---| +| Взять следующую ready-таску | `mcp__mappa__task_claim_next(project, owner)` | атомарно: лиз + таска; → `{ok, token, task}` | +| Продлить лиз | `mcp__mappa__task_heartbeat(project, claim_token)` | долгие таски | +| Создать таску | `mcp__mappa__task_create(project, slug, title?, description?, status?, priority?, due?, claim_token)` | под лизом; per-type номер (решение 20) | +| Закрыть таску | `mcp__mappa__task_close(project, id, claim_token)` | под лизом | +| Прочитать таску | `mcp__mappa__entity_get(id)` | id internal из search/claim | +| Список борда | `mcp__mappa__entity_search(q, type='task', project=<имя>, limit)` | все статусы | +| Дерево parent_of | `mcp__mappa__graph_tree(root, depth?, fields?, limit?)` | зонтики/иерархия | +| Связанные сущности | `mcp__mappa__graph_neighbors/backlinks(id)` | рефы к таске | +| Просрочка | `mcp__mappa__admin_overdue_scan(project?)` | P2-джоба: notify в инбокс, без мутаций | +| Уведомление при закрытии | `mcp__mappa__inbox_send(project=, from=<своя>, subject, body)` | письмо комиссионеру | + +**Лиз = лок на запись (решение 19).** Одна строка leases на проект: если другой +агент держит лиз — `task_claim_next` вернёт **422 busy**. Это серверный аналог +старого `.tasks/.lock`: проверять «а не поллер ли работает» руками не нужно — +сам claim скажет. Чтения лиза не требуют. + +**Рефы и id (#1037/#1028).** Таски наружу несут `ref: "t:N"` полным именем +первым полем (`task:N`, конвенция #1028), `num` следом, глобальный `id` — +internal (последним, для addressing в тулах). Ссылайся на таску +`[[task:N]]`/`task:N` в прозе (слаг/имя первым, реф как якорь: «таска +`mappa-task-work` (task:1062)»), никогда `#<глобальный id>`. + +## Статусы (эмодзи для презентации) + +| Эмодзи | Статус | Значение | +|---|---|---| +| ⚪ | `ready` | не начата, полностью определена | +| 🔴 | `active` | в работе (обычно одна) | +| 🟡 | `paused` | в процессе, возобновляема | +| 🔵 | `blocked` | ждёт внешнего входа | +| 🟢 | `done` | закрыта | + +Не путай: 🟢 — *done*, не «готово». Ready — ⚪. + +--- + +## Цикл + +### Фаза 0 — Ориентация + +1. **Инбокс-свип** — `mcp__mappa__inbox_monitor(project=<имя>)`: непрочитанные + письма могут менять план. Обработай каждое по `mappa-messaging`. +2. **Борд** — `entity_search(q, type='task', project=<имя>, limit=50)`: отсортируй + по статусу (🔴 → 🟡 → ⚪), по одной строке на таску, цитируй slug. +3. Если user назвал таску — `entity_get(id)` по её рефу/номеру. +4. Подтверди одним предложением: «Мы в середине X, следующий шаг — Y». +5. Спроси, верен ли план, перед действиями. + +### Фаза 1 — Выбор работы (claim, priority/due) + +1. `mcp__mappa__task_claim_next(project, owner)` — атомарно: лиз + следующая + ready-таска. `owner` = `::`. + Порядок выдачи: **P0-пул первый, внутри по дедлайну (просроченные первыми), + потом P1, потом P2**; отсутствующий priority = P1 (task-priority-due). +2. **Локально-первая рекомендация** — борд cwd первым; кросс-проект — футонота + (`Cross-project: N 🔴 active — см. tasks_aggregate`) только если N>0 и в cwd + нет активной 🔴. Кросс-проектные ургенты — информация, не драйвер «что делать здесь». +3. **Priority/Due — территория человека (раздел task-priority-due):** + - Агент ставит `priority`/`due` **только при создании** таски (явные параметры + или строки `**Priority:** P0|P1|P2` / `**Due:** yyyy-mm-dd` в description). + Отсутствует → дефолт P1, без дедлайна. + - **После создания агент не меняет** приоритет/дедлайн — прецедент человека + структурный (update агентами отклоняется сервером). Обнаружил, что таска + на самом деле P0 → паркуй вопрос человеку, не бампай сам. + - **Просрочка:** due < today при ready/active → `admin_overdue_scan` уведомляет + в инбокс **однократно, без мутаций** — никакого авто-бампа/авто-смены приоритета. + +### Фаза 2 — Исполнение + +- **Одна активная таска** 🔴 на проект. Не параллель. +- Читай description + per-task файл (`.md`, где есть) до старта. +- Долгие таски: `task_heartbeat(project, claim_token)` (лиз по TTL, дефолт 600s). +- **`session_break` gate** (из task-loop): если в description таски есть маркер + `session_break` — после close НЕ клейми следующую: печатай + `🔚 SESSION BOUNDARY …` и останавливайся (домен-свитч / milestone / тяжёлая инфра). + +### Фаза 3 — Сдача (close + review-umbrella) + +1. **Pre-close coverage check.** Собери acceptance criteria из description. Для + каждого — evidence: тест в диффе, артефакт, ссылка на дизайн. Нет evidence на + критерий → спроси user'а «закрывать или подождать coverage'а». +2. Resolve/drop открытые вопросы. +3. `task_close(project, id, claim_token)` → статус `done`. +4. **Notify-письмо (кросс-проектные таски).** Если таска пришла из другого + проекта (в description/meta есть `from:`/`notify:`) — `inbox_send` + комиссионеру: `project=`, `subject="[event: closed] "`, + body = итог (сделано, acceptance, ссылки). Живая сессия пишет сама. + Таска 🟢 ≠ комиссионер узнал. +5. **Review-umbrella для impl-тасок** (канон `mappa-delegation`): если таска + имплементационная и закрыта — парная `-review` уже должна быть + создана при постановке (status=blocked, blocker=impl#); закрытие impl + разблокирует ревью. Не создавай review сам, если её не было — это работа + постановщика; упомяни в close-note. +6. Дополни summary-строку в handoff/вики при наличии. + +### Пауза / переключение / конец сессии + +1. Текущая 🔴 → `task_close` если завершена (см. Фазу 3), иначе пометь + `status=paused` (owner остаётся; «where stopped» — в description или handoff). +2. **Инбокс-свип** на границе тасок (`inbox_monitor`). +3. Возьми следующую: `task_claim_next` (лиз + таска). Прежняя остаётся 🟡. +4. Подтверди ориентацию перед стартом. + +> **Never lose Where I stopped** — критичное поле: в description (последний +> абзац) или в handoff-сущности (`mappa-closing-ritual`). Перед концом сессии +> обязательно запиши handoff. + +--- + +## Loop-mode — «поработай очередь» + +Один триггер-сёрфейс: «поработай очередь» / «work the queue» / «прогони доску» +→ этот режим. Work the board **в этой сессии**: claim → работа → close → claim, +пока очередь не пуста или user не сказал стоп. **Интерактивный цикл, не демон.** + +``` +claim_next(project, owner) → пусто? → STOP «борд пуст» (не поллить) + ↓ таска +работа в этой сессии (read description + .md) + ↓ +завершена? нет → park: blocked (внешний) | paused (возобновляемо) → claim_next + ↓ да +consult_policy (из claim): human-only/strict-human → STOP перед close/commit, спросить user + ↓ auto +pre-close coverage check → task_close + ↓ +session_break на таске? → да: печатай 🔚 SESSION BOUNDARY, STOP + ↓ нет +claim_next … +``` + +- **Пустая очередь — естественный стоп, не wait-loop.** Нет `CronCreate`, нет + спавна субагента, нет коротких поллеров — это работа отдельного поллера. + Длинный watch («работай пока не скажу стоп» + явно «продолжай проверять») — + только один `ScheduleWakeup` с интервалом ≥1200s, никогда `CronCreate`. +- **Не завершаемая таска:** внешний блокер → `status=blocked` + blocker + (конкретный факт + что нужно); прервал ты (бюджет/стоп) → `status=paused` + + where_stopped. Одна упавшая таска не останавливает цикл — паркуй и дальше. +- **Heartbeat:** claim живёт ~10 мин — если таска дольше ~8 мин, `task_heartbeat` + периодически. +- **Consult-гейт:** `auto` → автопилот до close; `human-only`/`strict-human` → + работай, затем **STOP перед close/commit** и спроси user. Push никогда не + автоматический (project-discipline Rule 4: commit freely, push по явному + гранту). + +--- + +## Формат таски (из task-format) + +### Primary: mappa task_create + +Создание задач — **через тул, не руками** (решение 20): сначала лиз +(`task_claim_next`) → `task_create`. Номер `t:N` назначает сервер — не выдумывай. + +``` +mcp__mappa__task_create( + project: <имя проекта>, // обязателен + slug: , // обязателен, латиница + title: <одна строка>, // опционально + description: , // тело; [[refs]] → рёбра (решение 4) + status: ready | active | paused | blocked | done, // по умолчанию ready + priority: P0 | P1 | P2, // только при создании; отсутствует → P1 + due: yyyy-mm-dd, // только при создании; отсутствует = нет + claim_token: <токен лиза проекта> // мутация под лизом (решение 19) +) +``` + +Slug-правила: короткий, lowercase, kebab-case, латиница. Description — markdown, +`[[refs]]` на связанное. Priority/Due — при создании ИЛИ строками в description +(`**Priority:** P0|P1|P2`, `**Due:** yyyy-mm-dd`; явные параметры переопределяют). + +### Legacy: блок .tasks/STATUS.md (интерм до флипа поллера) + +Пока файловый поллер не переключён на mappa (#984), блоки в `.tasks/STATUS.md` +обязаны строгому формату — иначе поллер молча пропускает: + +```markdown +## ⚪ [#1234 my-task-slug] — One-line description. + +**Status:** ready +**Created:** 2026-08-23 +**Where I stopped:** (not started) +**Next action:** First concrete step the claiming agent runs. +**Branch:** master +**Weight:** needs-claude +**Notify:** OpeItcLoc03/workshop + + +--- +``` + +Три load-bearing правила: **(1)** шапка точно `## [# ] — ` +(h2, один emoji, `[# ]`, разделитель ` — `); **(2)** поля — строки +`**Label:** value`, буллеты игнорируются; **(3)** `**Created:**` обязателен. + +Поля, которые разбирает поллер: `**Weight:**` (cheap-ok | needs-claude | +needs-human — **обязателен** для авто-взятия), `**Notify:**` (/), +`**Requirements:**`, `**Runtime allowed:**`, `**Consult policy:**`, `**Blocker:**` +(только на 🔵), `**Priority:**`/`**Due:**` (как выше). `**Owner:**/`**Claim +token:**/`**Claim expires at:**` — claim-штамп, пишет и чистит поллер; залипший +штамп на ⚪ блокирует поллер. + +**Weight — поле, решающее взятие:** без `**Weight:**` поллер паркует в 🔵 +(`no backend for weight_tier: unknown`). Обычный код → `needs-claude`; +критикал-инфра (поллер, MCP-серверы, деплой, CI, git-хуки) → `needs-human`. + +--- + +## Failure modes + +- **422 busy** на `task_claim_next` → лиз держит другой агент; не параллель, + retry позже или спроси user. +- **task_close на незавершённую** → никогда. Park (blocked/paused). +- **claim истёк (zombie)** → не бросай claimed-таску: park/close по факту. +- **notify не указан (legacy)** → без него boss не узнает о завершении. +- **weight не указан (legacy)** → поллер паркует (no backend for weight_tier). +- **update Priority/Due после создания** → сервер отклоняет; паркуй вопрос + человеку, не бампай сам. + +## What NOT to do + +- **Не выдумывай номера** — `t:N` назначает сервер (решение 20). +- **Лиз-дисциплина:** мутации — только под лизом; 422 busy = кто-то другой пишет. +- **Одна активная таска** — только одна 🔴 на проект. +- **Never close без coverage check** — evidence на каждый acceptance criterion. +- **Не закрывай незавершённое** — park, не close; не оставляй claimed-таску. +- **Не бампай priority/due после создания** — территория человека. +- **Не «решай» задачи письмом/в чате** — борд — единственный источник правды + (канон mappa-messaging: «если это не на доске — это не задача»). +- **Не полли пустую очередь** — пусто = стоп и отчёт; без демона/CronCreate. +- **Не автопилоть human-only/strict-human** через close/commit; push — только по гранту. +- **Не батчи tasks_create в один репо** — sha-lock конфликты; сериализуй. + +## Red flags — STOP + +- «Поставлю таймер проверять новые таски» → нет. Стоп на пустой очереди. +- «Спавну фонового воркера гнать доску» → нет. Один цикл, эта сессия. +- «Таска не готова, но закрою и отмечу» → никогда. Park. +- «Приоритет у таски явно P0, сам бампну» → нет. Вопрос человеку. + +--- + +## Reference + +- Делегирование (постановка на агентов): `mappa-delegation`. +- Почта (covering-письма, notify): `mappa-messaging`. +- Знание (wiki-ингест после закрытия): `mappa-knowledge`. +- Финиш сессии (handoff write): `mappa-closing-ritual`. +- Старт сессии (pull/handoff/inbox/snapshot): `mappa-session-orient`. +- Промоушен (review-umbrella): `mappa-brainstorm-promote`. +- Кросс-проектный обзор: `using-system-snapshot` (liveness) / `mcp__projects-meta__tasks_aggregate`. diff --git a/skills/task-format/SKILL.md b/skills/task-format/SKILL.md deleted file mode 100644 index 33b034c..0000000 --- a/skills/task-format/SKILL.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -name: task-format -author: ours -version: 0.4.0 -description: > - Use when creating or editing a task so it is actually claimable and routed — - not silently skipped. Primary channel: **mappa** — create via - `mcp__mappa__task_create` (схема ниже), не руками. Legacy: пока файловый - поллер (agents-task-runner) не переключён на mappa (#984), блоки в - `.tasks/STATUS.md` обязаны совпадать со строгим форматом (шапка, поля - Weight/Notify), иначе поллер молча пропускает. Triggers: «оформить таску для - поллера», «формат таски», «task block format», «make a task the poller will - pick up», «add Weight/Notify», poller / agent-runner not claiming a task. ---- - -# task-format - -Канон создания задачи — **через тул**, не рукописным блоком. Поллер (автономный -раннер) разбирает задачи строгими правилами; формат задаёт, какая таска будет -взята, отмаршрутизирована и зарепорчена, а какая молча пропущена. - -> Создаёшь задачу для **другого** проекта/агента? См. `delegate-task` — он ведёт -> через тул + письмо. Работа с бордом (claim/close/status) — `using-tasks`. - -## Primary: mappa task.create - -Создание задач в mappa (решение 14/15: мета в сервисе) — только через -`mcp__mappa__task_create`, никогда руками вставляй блоки. Тул сам назначает -per-type номер (`t:N`, решение 20) и пишет сущность. - -``` -mcp__mappa__task_create( - project: <имя проекта>, // обязателен - slug: , // обязателен, латиница - title: <одна строка>, // опционально - description: , // тело; [[refs]] → рёбра (решение 4) - status: ready | active | paused | blocked | done, // по умолчанию ready - priority: P0 | P1 | P2, // важность; отсутствует → P1 (task-priority-due) - due: yyyy-mm-dd, // дедлайн; отсутствует = нет (task-priority-due) - claim_token: <токен лиза проекта> // мутация под лизом (решение 19) -) - -**Priority/Due (task-priority-due, #1045):** задаются **только при создании** -— либо явными параметрами `priority`/`due`, либо строками в description -(`**Priority:** P0|P1|P2`, `**Due:** yyyy-mm-dd`; явные параметры переопределяют -парсинг). После создания агент приоритет и дедлайн **не меняет** — прецедент -человека структурный (update агентами отклоняется сервером). Обнаружил, что -таска на самом деле P0 → паркуй вопрос человеку, не бампай сам. -``` - -**Мутация под лизом (решение 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 -## ⚪ [#1234 my-task-slug] — One-line description. - -**Status:** ready -**Created:** 2026-08-23 -**Where I stopped:** (not started) -**Next action:** First concrete step the claiming agent runs. -**Branch:** master -**Weight:** needs-claude -**Notify:** OpeItcLoc03/workshop - - ---- -``` - -Три load-bearing правила: - -1. **Шапка точно:** `## [# ] — ` — h2, один emoji, - `[# ]` (глобальный номер, без ведущих нулей), разделитель - ` — ` (пробел + em-dash + пробел). Несовпавшая шапка = задача не видна вообще. -2. **Поля — строки `**Label:** value`.** Буллеты и проза игнорируются. -3. **`**Created:** yyyy-mm-dd` обязателен** — пишется один раз при создании. - -Номера legacy-блоков назначает сервер (`tasks_create` из счётчика -`OpeItcLoc03/agenda/task-counter`) — **никогда не выдумывай номер руками**. - -### Поля, которые поллер разбирает - -| Field | Format | Meaning | -|---|---|---| -| `**Weight:**` | `cheap-ok` \| `needs-claude` \| `needs-human` | Тир маршрутизации. **Обязателен** для авто-взятия. | -| `**Notify:**` | `/` | Инбокс-адрес для событий close/park/delivery-failure. | -| `**Requirements:**` | CSV (`needs-db, needs-secrets`) | Capability-гейт: агент должен держать ВСЕ. | -| `**Runtime allowed:**` | CSV (`claude-opus`) | Runtime-whitelist. | -| `**Consult policy:**` | `auto` \| `human-only` \| `strict-human` | Эскалация consult; default `human-only`. | -| `**Blocker:**` | CSV blocker-slug'ов | Только на 🔵; авто-unblock при 🟢 всех. | -| `**Priority:**` | `P0` \| `P1` \| `P2` | Важность (task-priority-due). Отсутствует = `P1`. Влияет на порядок выдачи `claim_next` (P0-пул первый, внутри по дедлайну). **Ставится только при создании** — после агенты не меняют. | -| `**Due:**` | `yyyy-mm-dd` | Дедлайн (task-priority-due). Просроченные (due < today, ready/active) → overdue-scan уведомляет в инбокс однократно. Отсутствует = нет дедлайна. | -| `**Next action:** / **Where I stopped:** / **Branch:**` | free text | Резюмируемость. | - -`**Owner:** / **Claim token:** / **Claim expires at:**` — claim-штамп, пишет и -чистит поллер. Не автори руками; залипший штамп на ⚪ блокирует поллер. - -**Weight — поле, решающее взятие:** без `**Weight:**` поллер берёт задачу, не -находит тир и паркует в 🔵 (`no backend for weight_tier: unknown`). Обычный код -→ `needs-claude`; критикал-инфра (поллер, MCP-серверы, деплой, CI, git-хуки) → -`needs-human` (никогда не авто). - -## Common mistakes - -| Mistake | Fix | -|---|---| -| Рукописный блок вместо `task_create` | Создавай через тул — номер/формат серверные. | -| `### Title` / буллеты вместо полей | `## [#n slug] — desc` + `**Field:** value`. | -| 🟢 для ready | 🟢 — done. Ready — ⚪. | -| Шапка `[slug]` без номера | `[#n slug]` — номер машинный ключ. | -| Выдуманный номер | Номер — только от сервера (task_create). | -| `**Created:**` отсутствует (legacy) | Добавить — обязательное поле. | -| Ссылка `#<глобальный id>` | Ссылайся `[[t:N]]` (решение 20/#1037). | -| Без `**Weight:**` (legacy) | Ставь всегда, или задача паркуется. | -| Агент бампает `**Priority:**`/`**Due:**` после создания | Нельзя — прецедент человека структурный; ставь только при создании, иначе сервер отклоняет. | -| Дефис/двоеточие вместо ` — ` в шапке | Разделитель — пробел + em-dash + пробел. | - -## Verify - -Задача корректна, когда: создана через `task_create` (или legacy-блок: шапка -`## [#n slug] — …`, emoji = `**Status:**`, `**Created:**` есть, поля — -`**Label:**` строки, есть `**Weight:**` и `**Notify:**`); slug kebab-case; -ссылки на неё — `[[t:N]]`. diff --git a/skills/task-loop/SKILL.md b/skills/task-loop/SKILL.md deleted file mode 100644 index ce207a8..0000000 --- a/skills/task-loop/SKILL.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -name: task-loop -author: ours -version: 0.1.0 -description: > - Use when the user asks you to work the task board yourself, in this - session, one task after another — «поработай очередь», «прогони доску», - «бери задачи по очереди», «работай пока не скажу стоп», «work the queue», - «drain the board», «keep working tasks until I say stop». Does NOT apply - to delegating work to another agent/project (→ delegate-task), to one - named task you already know (→ using-tasks), or to configuring the - background poller. ---- - -# task-loop - -Work the board **in this session**: claim the next ready task, do it, close it, claim the next — until the queue is empty or the user says stop. - -**Core principle:** an interactive loop, not a daemon. You stay in the chair. Empty queue → **stop and report**, never spin a wait-timer. No subprocess, no `CronCreate` (that schedules a *separate* session — exactly the daemon you're replacing), no short `ScheduleWakeup` poll — those are the unattended poller's job, not yours here. - -**REQUIRED SUB-SKILL:** `using-tasks` owns the board, the `.tasks/.lock` session lock, the `session_break` gate, and the pre-close coverage check. This skill drives the loop *through* those rules — it does not replace them. -**REQUIRED SUB-SKILL:** `project-discipline` — commit/push gate (Rule 4) and sensitive-artifact handling apply to every task you touch. - -## When to use - -**Activates:** «поработай очередь», «прогони доску», «бери задачи по очереди», «работай пока не скажу стоп», «work the queue», «drain the board», «keep working tasks until I say stop». - -**Does NOT apply:** -- Delegating work to another agent/project → `delegate-task`. -- One specific task you already named → `using-tasks` (switch/resume that task). -- Setting up / debugging the background poller or agent-runner → that is infra, not this loop. - -## The loop - -Run this cycle. One task at a time. - -```dot -digraph task_loop { - rankdir=TB; - claim [shape=box, label="tasks_claim_next\n(current project, confirm=true)"]; - empty [shape=diamond,label="task returned?"]; - stop [shape=box, label="STOP — report board drained"]; - work [shape=box, label="do the work this session"]; - done [shape=diamond,label="completed?"]; - park [shape=box, label="park: blocked (external) | paused (resumable)"]; - gate [shape=diamond,label="consult_policy = human-only/strict-human?"]; - consult [shape=box, label="STOP before close/commit — consult user"]; - close [shape=box, label="pre-close coverage check → tasks_close"]; - brk [shape=diamond,label="session_break marker on closed task?"]; - boundary[shape=box, label="STOP — print SESSION BOUNDARY"]; - - claim -> empty; - empty -> stop [label="no ready tasks"]; - empty -> work [label="yes"]; - work -> done; - done -> park [label="no"]; - done -> gate [label="yes"]; - gate -> consult [label="yes"]; - gate -> close [label="auto"]; - close -> brk; - brk -> boundary [label="yes"]; - brk -> claim [label="no"]; - park -> claim; -} -``` - -1. **Claim** the next ready task with `tasks_claim_next(claimer_identity, filter, confirm=true)`. - - `claimer_identity` = `::` (e.g. `DESKTOP-NSEF0UK:claude-opus:`). - - `filter.project` = **the current project** (qualified `/`) by default. Only widen to other projects when the user explicitly asks ("прогони все доски" / passes a project list). - - The server already excludes `weight: needs-human` and anti-self-review tasks — you will never claim those. -2. **No task returned** → the queue is drained. **STOP** and report (see *Empty queue*). Do not poll. -3. **Do the work this session.** All your tools are available. Read the task description and per-task `.md`. Set the task `active` if it isn't already. -4. **Honor the gate before the irreversible step.** Use the `consult_policy` returned by the claim: - - `auto` → full autopilot through close. - - `human-only` / `strict-human` → do the work, then **STOP before `tasks_close` / commit** and consult the user. Don't barrel through. - - **Push is never automatic** regardless of policy — `project-discipline` Rule 4 (commit freely, push only on an explicit per-session grant). -5. **Close** with the `using-tasks` pre-close coverage check, then `tasks_close(target_project, slug, confirm=true, note=…)`. -6. **session_break gate.** After the close, **before claiming the next task**, honor the `using-tasks` `session_break` check: if the closed task carries the marker → print the `🔚 SESSION BOUNDARY` line and **STOP** (do not claim next). Otherwise → back to step 1. - -## When a task can't be finished - -Never leave a claimed task hanging (its claim expires in 10 min and it returns as a zombie), and never `tasks_close` unfinished work (that lies to the board). - -- **External / unresolvable blocker** discovered mid-task (missing upstream, needs a human decision, scope change) → `tasks_update(slug, status="blocked", blocker="")`. Roll back partial work that would break the build. Then continue the loop (the blocker is isolated; the next claim won't return this task). -- **Interrupted or resumable by you** (you ran out of budget, the user stops you mid-task) → `tasks_update(slug, status="paused", where_stopped=…, next_action=…)`. - -A single failing task does not stop the loop — park it and move to the next. - -## Empty queue & stopping - -The loop ends on the **first** of: -- **Empty queue** — `tasks_claim_next` returns no ready task → stop, report what you closed/parked, and wait for the user. Do **not** `ScheduleWakeup`, `CronCreate`, or sleep-poll for new tasks. -- **Explicit user signal** — «стоп», «хватит», «отбой». Park any in-flight claimed task (paused) before stopping. -- **Budget** — `budget.remaining()` near zero → park the current task (paused) and report. - -**Long-running watch (opt-in only).** If the user explicitly says «работай пока не скажу стоп» *and* wants you to keep checking for newly-arrived tasks, use **`ScheduleWakeup`** — it re-invokes *this* session — with a **long** interval (≥1200 s). **Never `CronCreate`** even here: it starts a *separate* scheduled session, i.e. the daemon this skill exists to avoid. And never a short poll. Default is still stop-on-empty; only arm a wakeup on an explicit standing request. - -## Heartbeat - -A claim lives 10 minutes. If a single task will take longer than ~8 minutes, call `tasks_heartbeat(slug, claim_token)` periodically to keep the claim alive. Short tasks need no heartbeat. (The in-session `.tasks/.lock` is a separate 2-hour lock owned by `using-tasks` session start/end — don't manage it from the loop.) - -## What NOT to do - -- **No daemon, no `CronCreate`, no spawned claude, no subprocess** to "run the queue" — `CronCreate` starts a separate scheduled session; the whole point is you do it in *this* session. -- **No busy-poll on empty** — empty queue is a natural stop, not a wait-loop. A short `ScheduleWakeup` loop burns tokens for nothing. The only exception is the explicit long-watch opt-in above (a single ≥1200 s `ScheduleWakeup`, never `CronCreate`). -- **Don't widen scope silently** — default to the current project; claim other boards only when the user asks. -- **Don't `tasks_close` unfinished work** and **don't leave a task claimed** when blocked — park it (blocked/paused). -- **Don't skip the `session_break` gate** between tasks — a milestone/domain-switch marker means stop, even if more tasks are ready. -- **Don't autopilot through a `human-only`/`strict-human` task's close/commit**, and **never auto-push** — consult first. -- **Don't blind-retry** a task that failed for an external reason — diagnose once, record the blocker, move on. - -## Red flags — STOP - -- "I'll set a timer to check for new tasks" → no. Stop on empty; report. -- "I'll spawn a background worker to drain faster" → no. One task at a time, this session. -- "User said work-until-stop, I'll `CronCreate` a recurring run" → no. `CronCreate` is a separate scheduled session = the daemon. Long-watch uses a single long `ScheduleWakeup` on *this* session. -- "It's sensitive but consult_policy says auto, I'll just commit" → push still needs a grant; sensitive close still respects the gate. -- "The task isn't done but I'll close it and note it" → never close unfinished. Park it. diff --git a/skills/using-tasks/README.md b/skills/using-tasks/README.md deleted file mode 100644 index 95d095c..0000000 --- a/skills/using-tasks/README.md +++ /dev/null @@ -1,169 +0,0 @@ -# using-tasks - -Runtime policy for keeping compressed working context across parallel tasks -in a monorepo. The agent reads and updates `.tasks/` so every session starts -oriented and every switch costs seconds, not minutes. - -`using-tasks` governs the task board. **Канал — mappa** (решение 14/15): борд = -сущности `type=task` в сервисе (см. SKILL.md v2.0.0). Файловый `.tasks/` — легаси; -`setup-tasks` умер. - -> Renamed from `task-status-wiki` at v1.0.0. - -## When it triggers - -- User is switching between tasks, resuming a paused task, starting a new - one, or asks "where were we" / "what's the status". -- User says: "use task management system", "pause", "switch to X", - "update status". -- Any context-switching or multi-task coordination question in a code - project. -- Борд читается из mappa (`entity_search(type='task', project=…)`); - файловый `.tasks/` — легаси, ничего настраивать не нужно. - -## Structure - -``` -/ -└── .tasks/ - ├── STATUS.md ← board: one block per task, sorted by priority - └── .md ← deep context per task, one file each -``` - -Commit `.tasks/` to git — decision history is valuable, diffs show how -thinking evolved. - -## STATUS.md format - -```markdown -# Task Board -_Updated: YYYY-MM-DD_ - -## 🔴 [task-slug] — short description -**Status:** active | paused | blocked | done -**Where I stopped:** one sentence — the exact thought or action interrupted -**Next action:** one concrete step to resume immediately -**Blocker:** (only if blocked) what is preventing progress -**Branch:** git branch name - ---- -``` - -Status legend: - -| Emoji | State | Notes | -|---|---|---| -| 🔴 | Active | Currently worked on. **Only one at a time.** | -| 🟡 | Paused | In progress, resumable. | -| ⚪ | Ready | Defined, not started. | -| 🟢 | Done | Kept until merged. | -| 🔵 | Blocked | Waiting on external input. | - -## Per-task file format (`.md`) - -Sections, in order: **Goal** (one paragraph — what this achieves and why), -**Key files** (`path/to/file.ts:42` style — specific lines when relevant), -**Decisions log** (reverse-chronological, append-only — past entries are -immutable), **Open questions**, **Completed steps**, **Notes** (temporary -hypotheses, links). - -## Operations - -### Session start - -1. Check the mappa board: `entity_search(type='task', project=<имя>)`. - Файлового `.tasks/STATUS.md` больше нет — setup-tasks умер. -2. Read `STATUS.md`. -3. If user names a task, read its `.md`. -4. Confirm in one sentence: "We're in the middle of X, next step is Y." -5. Ask if the plan is still correct before doing anything. -6. If `_Updated` is more than 3 days old, flag it and ask the user to - confirm current state. - -### Session end / pause / switch - -1. Update `STATUS.md`: set the current task to 🟡, refresh "Where I stopped" - and "Next action". -2. Append non-obvious decisions to `.md` Decisions log. -3. Move finished items to "Completed steps". -4. Commit: `git add .tasks/ && git commit -m "chore: update task status []"`. - -### Task switch - -1. Run session-end ops for the current task. -2. Read the target `.md`. -3. Set the target to 🔴 in `STATUS.md` (demote previous active to 🟡). -4. Confirm orientation before starting work. - -### New task - -1. Ask: slug, goal, known key files, branch. -2. Create `.md` with Goal and Key files populated. -3. Add a ⚪ block to `STATUS.md`. -4. Create / checkout the branch if missing. - -### Task completion - -1. **Pre-close coverage check** — list acceptance criteria, locate - evidence (tests, smoke-test artefacts, manual checklist ticks, design - doc refs). Missing evidence → ask the user before closing; never auto-close. -2. Resolve or drop all open questions. -3. Set status to 🟢 in `STATUS.md`. -4. Append a final summary line to the Decisions log. -5. Remind the user to delete the branch after merge. - -### Post-commit task closure prompt - -After a `feat:` / `fix:` commit the agent prompts: -"эта работа закрывает таску ``?". Slug candidates: commit-message -scope, current branch, most recent `Where I stopped`. If yes → run the -coverage check above. Skips `chore:` / `meta:` / `docs:` commits. - -Forces a fresh-while-fresh decision, instead of letting shipped code sit -under a stale ⚪ block. - -### Recommendations / "what's next" trigger - -When the user asks «что дальше», «срочные», «куда копаем», "what next", -"status", or on session-start — recommend in this order: - -1. **Local cwd-project board** ranked 🔴 → 🟡 → ⚪. Cite slugs. -2. **One footnote line** if relevant: `Cross-project: N 🔴 in other repos - (см. mcp__projects-meta__tasks_aggregate).` Only if N>0 and no local 🔴. - -Explicit "по всем проектам" / "across all projects" flips the order. -Pairs with `using-projects-meta`'s local-first rule (which covers reads; -this one covers recommendations). - -## Rules - -- **Never lose "Where I stopped".** Most critical field. If unclear, ask - before ending the session. -- **One sentence per `STATUS.md` field.** Compress, don't write prose. -- **Key files must be specific** — not "auth module" but - `packages/auth/src/useAuth.ts:87`. -- **Decisions log is append-only.** Past entries are immutable. -- **Commit after every session end.** `git log` is the history of thinking. -- **Always confirm orientation at session start.** State understanding - before acting. -- **One active task at a time** — only one 🔴 in `STATUS.md`. -- **Never close without coverage check.** See "### Task completion" - step 1. -- **Local-first recommendations.** cwd-project first; cross-project at - most one footnote line. - -## Install - -From the repo root: - -```bash -bash scripts/install.sh using-tasks -``` - -Works on Windows under git-bash, Linux, macOS. - -## See also - -- mappa — сервис-хост борда (`task_create`/`task_claim_next`/`task_close`, - per-type `t:N`). -- [`project-bootstrap`](../project-bootstrap/) — mappa-режим для новых проектов. diff --git a/skills/using-tasks/SKILL.md b/skills/using-tasks/SKILL.md deleted file mode 100644 index 324142c..0000000 --- a/skills/using-tasks/SKILL.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -name: using-tasks -author: ours -version: 2.0.0 -description: > - Policy skill for working with the project task board in Mappa (решения 14/15: - мета в сервисе). Use whenever switching between tasks, resuming a paused task, - starting a new task, asking «where were we», says «use task management system», - «pause», «switch to X», «what's the status», «update status», or tracking - progress across parallel workstreams. Board = сущности `type=task` в mappa - (чтение — карв-аут лиза; мутации — под лизом проекта, решение 19). Файловый - `.tasks/` — легаси; `setup-tasks` умер (нечего настраивать). ---- - -# using-tasks - -> Policy для поддержания сжатого рабочего контекста параллельных тасок. -> Борд проекта — сущности mappa: каждая таска `t:N` (per-type номер, решение 20) -> со статусом `ready|active|paused|blocked|done`, телом, owner'ом и рёбрами -> ([[refs]] → parent_of/ref, решения 4/6). Чтение — карв-аут лиза (решение 19); -> **любая мутация — под лизом проекта**. - -## MCP-поверхность - -| Операция | Тул | Примечание | -|---|---|---| -| Взять следующую ready-таску | `mcp__mappa__task_claim_next(project, owner)` | атомарно: лиз + таска; → `{ok, token, task}` | -| Продлить лиз | `mcp__mappa__task_heartbeat(project, claim_token)` | долгие таски | -| Создать таску | `mcp__mappa__task_create(project, slug, title?, description?, status?, claim_token)` | под лизом | -| Закрыть таску | `mcp__mappa__task_close(project, id, claim_token)` | под лизом | -| Прочитать таску | `mcp__mappa__entity_get(id)` | id internal из search/claim | -| Список борда | `mcp__mappa__entity_search(q, type='task', project=<имя>, limit)` | все статусы | -| Дерево parent_of | `mcp__mappa__graph_tree(root, depth?, fields?, limit?)` | зонтики/иерархия (решение 6) | -| Связанные сущности | `mcp__mappa__graph_neighbors/backlinks(id)` | рефы к таске | -| Уведомление при закрытии | `mcp__mappa__inbox_send(project=, from=<своя>, subject, body)` | письмо комиссионеру | - -**Лиз = лок на запись (решение 19).** Одна строка leases на проект: если другой -агент держит лиз — `task_claim_next` вернёт **422 busy**. Это серверный аналог -старого `.tasks/.lock`: проверять «а не поллер ли работает» руками не нужно — -сам claim скажет. Чтения лиза не требуют. - -**Рефы и id (#1037).** Таски наружу несут `ref: "t:N"` первым полем, `num` -следом, глобальный `id` — internal (последним, для addressing в тулах). -Ссылайся на таску `[[t:N]]` (в body → рёбра автоматически), никогда -`#<глобальный id>`. - -## Статусы (эмодзи для презентации) - -| Эмодзи | Статус | Значение | -|---|---|---| -| ⚪ | `ready` | не начата, полностью определена | -| 🔴 | `active` | в работе (обычно одна) | -| 🟡 | `paused` | в процессе, возобновляема | -| 🔵 | `blocked` | ждёт внешнего входа | -| 🟢 | `done` | закрыта | - -## Операции агента - -### Ориентация (session start) - -1. **Инбокс-свип** — `mcp__mappa__inbox_monitor(project=<имя>)`: непрочитанные - письма могут менять план. Обработай каждое по `inter-session-messaging`. -2. **Борд** — `mcp__mappa__entity_search(q='', type='task', project=<имя>, limit=50)`: - отсортируй по статусу (🔴 → 🟡 → ⚪), по одной строке на таску, цитируй slug. -3. Если user назвал таску — `entity_get(id)` по её рефу/номеру. -4. Подтверди одним предложением: «Мы в середине X, следующий шаг — Y». -5. Спроси, верен ли план, перед действиями. - -### Переключение / пауза / конец сессии - -1. Текущая 🔴 → `task_close` если завершена (см. закрытие), иначе пометь - `status=paused` через update-механику (owner остаётся; «where stopped» — - в body или handoff). -2. **Инбокс-свип** на границе тасок (`inbox_monitor`). -3. Возьми следующую: `task_claim_next` (лиз + таска). Прежняя остаётся 🟡. -4. Подтверди ориентацию перед стартом. - -> Примечание про «Where I stopped»: у mappa-таски нет отдельного поля — держи -> место остановки в `description` (последний абзац) или, для сессионного -> контекста, в **handoff-сущности** (`session-handoff`: summary/open_treks). -> Перед концом сессии обязательно запиши handoff — это аналог -> «Never lose Where I stopped». - -### Создание таски - -1. **Через тул, не руками** (решение 20): сначала лиз (`task_claim_next`) → - `task_create(project, slug, title, description, status='ready', claim_token)`. - Номер `t:N` назначает сервер — не выдумывай. -2. Slug: kebab-case, латиница. Description: markdown, `[[refs]]` на связанное. -3. Закрыть лиз не нужно — экспирится по TTL; мутации идут одним циклом. - -### Закрытие таски - -1. **Pre-close coverage check.** Собери acceptance criteria из description. - Для каждого — evidence: тест в диффе, артефакт, ссылка на дизайн. - Нет evidence на критерий → спроси user'а «закрывать или подождать coverage'а». -2. Resolve/drop открытые вопросы. -3. `task_close(project, id, claim_token)` → статус `done`. -4. **Notify-письмо (кросс-проектные таски).** Если таска пришла из другого - проекта (в description/meta есть `from:`/`notify:`) — `inbox_send` - комиссионеру: `project=`, `subject="[event: closed] "`, - body = итог (сделано, acceptance, ссылки). Живая сессия пишет сама. -5. Дополни summary-строку в handoff/вики при наличии. - -### Рекомендации / «что дальше» - -User спросил «что дальше», «status», «куда копаем» — рекомендую в порядке: - -1. **Локальный борд текущего проекта** (cwd): `entity_search(type='task', - project=<имя>)` — 🔴 → 🟡 → ⚪, по строке на таску, цитируй slug. -2. Одна footnote-строка если кросс-проектно релевантно: `Cross-project: N 🔴 - active (см. mcp__projects-meta__tasks_aggregate).` Только если N>0 и в cwd - нет активной 🔴. - -Кросс-проектные ургенты — информация, не драйвер «что делать здесь». - -## Правила - -- **Лиз-дисциплина.** Мутации — только под лизом; 422 busy = кто-то другой - пишет, не параллель. -- **Never lose Where I stopped** — критичное поле: в description + handoff. -- **Одна активная таска** — только одна 🔴 на проект. -- **Не выдумывай номера** — `t:N` назначает сервер. -- **Never close без coverage check** — evidence на каждый acceptance criterion, - иначе спросить. -- **Notify-письмо при закрытии** кросс-проектных тасок — статус 🟢 ≠ комиссионер - узнал. -- **Чтения — карв-аут.** `entity_search`/`entity_get`/`graph_*` не требуют лиза - и не блокируются чужим лизом. -- **Локально-первая рекомендация** — борд cwd первым; кросс-проект — футонота. -- **Ссылайся `[[t:N]]`**, не глобальным id (#1037). - -## Legacy (переходное) - -Файловый `.tasks/` (STATUS.md + per-task файлы) — легаси-канал, живёт пока -миграция/поллер не доедут. Не смешивай: новые таски — через mappa task_create; -старые борды читай напрямую (`.tasks/STATUS.md`), если они ещё в файлах. -`setup-tasks` умер — файловые борды больше не настраиваются.