# Формат задач, целей и индексов Заголовок, мета-строку и строку индекса ставит `tasks.py add` — руками их не пишут. Этот файл описывает, что именно скрипт создаёт и что проверяет `check`; тело задачи (одну фразу, критерии, рамки, контекст) дописывает агент. ## Файл задачи `items/.md`: ```markdown # Тай-брейк при равной полноте **Секция:** ядро — вышла из спринта: остаток писал нерешённое в журнал · **Теги:** goal:merge-robustness, sprint:2026-08 При столкновении точек выигрывает более полная, но при равной полноте побеждает последняя доставка — а она систематически беднее первой. ## Критерии приёмки - повторный прогон свёртки даёт тот же отпечаток состояния — оракул: команда сверки - накопительная метрика за сутки не уменьшается после повторной доставки — оракул: тест - в логе видно, какая из двух точек выиграла и почему — оракул: глазами по логу прогона ## Рамки Схема не трогается; данные только читаются; перезапуск сервиса допустим. Связано: решение о канонической форме содержимого. ``` - **Заголовок H1** — он же заголовок строки в индексе, дословно. Тип кодируется префиксом `[goal]` / `[idea]` / `[epic]`; обычная задача — без префикса. Отдельного поля типа **нет**: два места для одного факта разъезжаются, а префикс виден прямо в индексе, где и принимается решение «брать или не брать». - **Мета-строка** — первая непустая строка после заголовка. Обязательна секция, причина после тире желательна (именно она объясняет, почему задача здесь оказалась — в том числе «вышла из спринта: …»), теги опциональны. Поля разделяются ` · `, порядок свободный. `·` — служебный разделитель: в тексте причины его быть не должно. - **Тело** — одна фраза «что станет наблюдаемо иначе», критерии приёмки, рамки, контекст, ссылки. Пишется на языке документации проекта. Тело — не план реализации и не спецификация: принятое и реализованное переезжает в документацию проекта, а файл задачи удаляется. ### Критерии приёмки 2–5 проверяемых утверждений, **у каждого назван оракул**. Не «работает корректно», а «повторный прогон даёт тот же отпечаток — оракул: команда сверки». Это не второе определение готовности, а проектная конкретизация вопроса «по чему видно, что закончено» из теста готовности ниже: там сказано «признак завершённости», здесь — «признак плюс чем проверяется». **У идей критериев нет — именно поэтому они идеи.** **Критерии — пол, но расхождение с ними есть дефект критериев.** Если приёмщик видит, что критерии закрыты, а суть задачи не достигнута, он **правит критерии и возвращает задачу исполнителю**, а не держит невидимое сверх-требование. Иначе исполнитель никогда не знает, закончил ли, и мотивирован занижать критерии заранее. ### Рамки Одна строка: чего касаться нельзя, что перезапускается, что считается необратимым, трогается ли схема данных. **Свойства репозитория сюда не пишутся** — номер последней миграции, версия зависимости, хеш: в лежалой задаче они протухают молча и становятся ложной рамкой. Снимок берётся при постановке, а не при заведении. ### Вопросы Неразобранное решение человека живёт разделом `## Вопросы` **плюс тегом `question`**. Тег — то, по чему вопрос виден снаружи файла (`list --questions`) и чем работает правило «задача с открытым вопросом в набор не берётся». Раздел без тега или тег без раздела — дрейф, `check` о нём скажет. Ответ записывается в тело, тег снимается `edit --rm-tag question`, а хук переписывается: «Решено: …» на вопрос «почему это лежит в беклоге» уже не отвечает. ## Файл цели ```markdown # [goal] Прочность слияния **Секция:** кусты · **Теги:** decomposed Ради чего: точки из разных доставок сходятся в один часовой объект, и сегодня исход столкновения зависит от порядка доставки, а не от содержания. ## Завершение Достигнута, когда исход слияния не зависит ни от порядка, ни от времени доставки, и это подтверждено повторным прогоном на живом корпусе. ``` - **Задачи цели здесь не перечисляются.** Перечень даёт `tasks.py list --goal <слаг>`; хранимый список стал бы третьим индексом и поехал бы на первой же закрытой задаче. - **Раздел «Завершение»** — то, по чему видно, что цель достигнута. Он же отличает «цель ещё не декомпозирована» от «все её задачи закрыты»: пометка вроде тега `decomposed` или строки в теле ставится, когда цель разложена на задачи. - Цель живёт в `PLAN.md` и **никогда** — в `BACKLOG.md` или `SPRINT.md`. ## Слаг Латиница и цифры, kebab-case, без ведущих, хвостовых и двойных дефисов (`foo-bar`, не `-foo`, `a--b`). Именуется **по сути, а не по текущей формулировке**: заголовок будет переписан при переоценке, а слаг стоит в ссылках из других задач, коммитов и черновиков. **Транслита не заводим** — `tie-break-equal-completeness`, а не `taj-brejk-pri-ravnoj-polnote`: транслит нечитаем для того, кто ищет по смыслу, и не сокращается. Переименование слага — не правка, а перенос ссылок: делается одним атомарным проходом по всем местам, где слаг упомянут, иначе останутся битые ссылки, которых никто не проверяет. ## Индексы Строка везде одной формы: ```markdown - [Заголовок дословно](items/slug.md) — хук ``` Хук отвечает на «почему это лежит в беклоге» одним предложением: состояние, остаток, боль. Пересказ первого абзаца бесполезен — он уже есть по ссылке. | Файл | Что отвечает | Секции | | --- | --- | --- | | `PLAN.md` | какие есть цели, в каком порядке идёт линия и почему | линия (упорядоченная) и кусты | | `BACKLOG.md` | что **можно взять** — только задачи | секции проекта (по умолчанию ядро/инфра) | | `SPRINT.md` | какая цель и какой набор под неё | одна: «Набор» | | `REJECTED.md` | что ушло без реализации и почему | — | Секции — **единственные заголовки `##` в индексе**: любой другой `##` в преамбуле проверка сочтёт секцией. Внутри секции беклога порядок значения не имеет — порядка в беклоге нет вовсе. В **линии** плана порядок значим и обосновывается прозой; двигают строку `move --section линия --after <другой>`. Индексы **производны**: расходятся с файлом — правим индексы (`check --fix`). Строку руками не пишут. `SPRINT.md` и есть артефакт заморозки: без него набор существует только в контексте сессии, и нарушение заморозки ненаблюдаемо. ## `REJECTED.md` Туда уходит задача, покинувшая беклог **без реализации**. Строку пишет `tasks.py close --reason`, а `check` следит за форматом: ```markdown - 2026-07-23 `versii-kachestvo-repaki` — Версии и качество одного тайтла. Причина: калибровка болей — не боль, ни разу не возникло за полгода. Была секция: инфра. ``` Реализованные сюда не попадают: у них остаётся коммит и документация. У выкинутой не остаётся ничего — и через квартал она возвращается тем же текстом. Это первое место, куда смотрит дедупликация при заведении. Запись не запрещает завести задачу заново: изменился контекст — заводим и ссылаемся на строку, объясняя, что изменилось. ## Теги Единственный механизм разметки, потому что `list --tag` уже умеет отбирать по ним порцию разбора. Отдельных полей мета-строки под это не заводим. - `goal:<слаг>` — цель, которой служит задача. Обязателен: задача без цели не попадёт ни в один спринт. - `question` — в файле есть неразобранный раздел «Вопросы». - `sprint:<слаг>` — задача заведена в этом спринте; по нему отбирается первая порция разбора («урожай спринта»). Свои теги проект заводит свободно (партия ревью `review-ГГГГ-ММ-ДД`, тема, источник) — словарь не фиксирован. В индексы теги не выносим: индексы производны, отбор делает `list --tag`, а не глаза. ## Тест «готова к взятию» Задача готова, если из файла отвечаются три вопроса: 1. **Что станет наблюдаемо иначе**, когда она сделана — снаружи: пользователю, владельцу сервиса или разработчику. «Отрефакторить X» — не ответ; «перестанет ломаться Y при Z» — ответ. 2. **По чему видно, что закончено** — критерии приёмки с оракулами. 3. **Какой цели она служит** — тег `goal:` и одна строка «почему именно этой». Не отвечается первый или второй вопрос → это **идея** (`[idea]`), её место в штурме. Не отвечается третий → либо цель есть и не проставлена, либо задача не служит ничему — тогда её не надо заводить. Отвечается всё, но задача не делается одним заходом и не мерджится целиком → **эпик** (`[epic]`), сперва декомпозиция. Эпик временен и исчезает после разбора; цель (`[goal]`) постоянна — не путать. Тест применяется при заведении и при переоценке. К старым задачам, которых операция не касается, задним числом не применяется — беклог не переоформляют «заодно».