скилл tasks: приоритет стал порядком строк в беклоге
Правило 4 переписано целиком. Было «порядка нет, есть цель», и обосновано это было тем, что на «что делать дальше» отвечает набор спринта. Набора нет — вопрос остался, отвечать нечем. Приоритет — свойство очереди, а не задачи, поэтому его дом индекс: то же исключение из правила 2, что и «в каком индексе лежит запись». Положи его в файл числом — два соседних файла смогли бы утверждать одно место, а строка индекса противоречить обоим. Цель и приоритет — независимые оси: очередь может идти поперёк целей. Расстановка — это move --after и move --first, и только они: руками поправленная строка не оставляет причины. Место сырья в конце секции из очереди изъято: оно производно от типа и заполненности, его назначает машина, приоритетом оно не становится. Схема состояний потеряла SPRINT.md и четыре перехода; шесть уставов типов, task-format, split, from-review и adopt переведены со «взятия в спринт» на ready.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: tasks
|
||||
description: Ведение задач и целей как каталога markdown-файлов (одна запись = один файл в items/ + строка в одном из индексов). У каждой записи есть тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение записи из диалога, разбор находок аудита/ревью, декомпозиция на независимо полезные части, штурм сырья, гигиена полей и проверка согласованности индексов. Использовать, когда просят добавить задачу/идею/цель, превратить находки ревью в задачи, разбить задачу, проработать идею, поправить формат или проверить беклог. Ритуал между спринтами — скилл session. Не реализует задачи — этим занимается пайплайн проекта.
|
||||
description: Ведение задач и целей как каталога markdown-файлов (одна запись = один файл в items/ + строка в одном из индексов). У каждой записи есть тип (goal, feature, fix, chore, research), и тип решает, каких разделов она требует и что с ней можно делать. Заведение записи из диалога, разбор находок аудита/ревью, декомпозиция на независимо полезные части, штурм сырья, гигиена полей и проверка согласованности индексов. Использовать, когда просят добавить задачу/идею/цель, превратить находки ревью в задачи, разбить задачу, проработать идею, поправить формат или проверить беклог. Расстановка приоритетов и разбор накопившегося — скилл groom. Не реализует задачи — этим занимается скилл решения задачи.
|
||||
---
|
||||
|
||||
# Задачи
|
||||
@@ -9,9 +9,9 @@ description: Ведение задач и целей как каталога mar
|
||||
строка **ровно в одном** индексе. Скилл владеет **форматом и содержимым**:
|
||||
заводит, редактирует, закрывает, разбирает находки ревью, дробит, штурмует сырьё.
|
||||
|
||||
Чем он **не** владеет: ритуалом между спринтами (разбор вопросов → разбор
|
||||
прошедшего спринта → переоценка → выбор цели и набор) — это скилл `session`; и
|
||||
выполнением задачи — это пайплайн проекта.
|
||||
Чем он **не** владеет: **очередью** — что делать следующим и что перестало быть
|
||||
важным, решает скилл `groom`, а этот скилл лишь даёт ему операции; и выполнением
|
||||
задачи — это пайплайн проекта.
|
||||
|
||||
## Шесть правил, из которых всё следует
|
||||
|
||||
@@ -35,27 +35,38 @@ description: Ведение задач и целей как каталога mar
|
||||
Поэтому **«зачем» живёт в мете файла**, а строка индекса его лишь
|
||||
повторяет: пока поле лежало только в индексе, восстановление пропавшей
|
||||
строки теряло его молча и навсегда. Единственное исключение намеренное: **в каком
|
||||
индексе лежит задача, знают индексы** — «в спринте» это свойство спринта, а
|
||||
не файла, поля-состояния нет.
|
||||
индексе лежит запись, знают индексы** — поля-состояния в файле нет. И
|
||||
**порядок строк в беклоге**: приоритет это свойство очереди, а не задачи, и в
|
||||
файле ему места нет (правило 4).
|
||||
3. **Причина переживает запись.** Выкинутая без причины задача вернётся через
|
||||
квартал тем же текстом. Реализованная оставляет след в коммите — выкинутая не
|
||||
оставляет ничего, поэтому у неё есть `REJECTED.md`.
|
||||
4. **Порядка нет, есть цель — но цель есть не у всякой задачи.** Приоритетов,
|
||||
«повысить» и «встать раньше» нет: «что делать дальше» отвечает набор спринта,
|
||||
а между спринтами порядок не нужен никому. Цель обязательна там, где она и
|
||||
есть содержание работы, — у **новой возможности** (`feature`). Починка,
|
||||
техдолг и разведка служат работоспособности, а не направлению, и живут без
|
||||
цели законно; в набор спринта они входят помимо его цели. Придуманная им цель
|
||||
— то же враньё, от которого спасает тип.
|
||||
4. **Приоритет — это порядок строк, а цель есть не у всякой задачи.** Очередь
|
||||
внутри секции беклога значима: **первая строка — то, что делают следующим**.
|
||||
Приоритет назначает человек на груминге, машина его не выводит и не угадывает.
|
||||
|
||||
Единственный порядок, который в беклоге всё-таки есть, **производен от типа**,
|
||||
а не назначен человеком: **сырьё** (`research` без раздела «Вопрос») стоит в
|
||||
конце своей категории. Его не берут, и между берущимся оно каждый раз требует
|
||||
открыть файл, чтобы это понять. Раз порядок выводится, его проверяет машина —
|
||||
и приоритетом он не становится.
|
||||
Прежде здесь стояло «порядка нет, есть цель», и обосновано это было тем, что
|
||||
на «что делать дальше» отвечает **набор спринта**. Набора больше нет, а
|
||||
вопрос остался — и без порядка отвечать на него стало нечем.
|
||||
|
||||
**Дом приоритета — индекс, а не файл.** Это то же исключение из правила 2,
|
||||
что и «в каком индексе лежит запись»: приоритет — свойство очереди. Положи он
|
||||
в файл числом, и два соседних файла смогли бы утверждать одно и то же место,
|
||||
а строка индекса — противоречить обоим.
|
||||
|
||||
Цель обязательна там, где она и есть содержание работы, — у **новой
|
||||
возможности** (`feature`). Починка, техдолг и разведка служат
|
||||
работоспособности, а не направлению, и живут без цели законно. Придуманная им
|
||||
цель — то же враньё, от которого спасает тип. **Цель и приоритет —
|
||||
независимые оси:** очередь может идти поперёк целей, и это законно.
|
||||
|
||||
Одно место в очереди назначено **не человеком, а типом**: **сырьё**
|
||||
(`research` без раздела «Вопрос») стоит в конце своей категории. Его не берут,
|
||||
и между берущимся оно каждый раз требует открыть файл, чтобы это понять. Раз
|
||||
это выводится, проверяет и чинит это машина.
|
||||
5. **Тип решает, что с записью можно делать.** Тип — единственная ось и первое
|
||||
поле меты: от него зависит, какие разделы обязательны в теле, нужна ли цель,
|
||||
берётся ли запись в спринт и в каком индексе живёт её строка. Словарь закрыт;
|
||||
берётся ли запись в работу и в каком индексе живёт её строка. Словарь закрыт;
|
||||
ни один тип не подошёл — значит, в записи их два, и её надо разделить.
|
||||
|
||||
## Раскладка
|
||||
@@ -70,14 +81,14 @@ description: Ведение задач и целей как каталога mar
|
||||
tasks/
|
||||
items/ задачи и цели файлами, <slug>.md, слаги английские
|
||||
ROADMAP.md состояние проекта: что уже умеет и чего ещё не умеет
|
||||
BACKLOG.md что можно взять — только задачи, целей здесь нет
|
||||
SPRINT.md текущий спринт: цель (или её отсутствие), набор, дата
|
||||
BACKLOG.md что можно взять — только задачи, целей здесь нет.
|
||||
Порядок строк в секции значим: это очередь
|
||||
REJECTED.md ушедшее БЕЗ реализации, с причиной и датой
|
||||
```
|
||||
|
||||
Правило, снимающее путаницу: **`BACKLOG.md` — то, что берут; `ROADMAP.md` — то,
|
||||
подо что берут.** Цель в спринт взять нельзя, поэтому в списке берущихся ей не
|
||||
место.
|
||||
подо что берут.** Цель в работу взять нельзя — берут её задачи, — поэтому в
|
||||
списке берущихся ей не место.
|
||||
|
||||
**Четыре секции роадмапа, и последняя отвечает на половину вопроса:**
|
||||
|
||||
@@ -99,7 +110,7 @@ tasks/
|
||||
роадмап, названный по-своему, читался бы только своим автором. Категории беклога
|
||||
(`Ядро`, `Инфра`) смысла не несут — это полки домена, и остаются делом проекта.
|
||||
Отсюда и разные имена поля меты: у цели **Секция** (часть роадмапа — состояние
|
||||
очереди), у задачи **Категория** (полка, в которую она вернётся из спринта).
|
||||
очереди), у задачи **Категория** (полка домена, на которой она лежит).
|
||||
|
||||
Отсюда четыре правила, которые проверяет `tasks.py check`: **состав закреплён**
|
||||
(чужая секция — ошибка, а не вольность), **все четыре обязаны быть** (нет
|
||||
@@ -118,24 +129,31 @@ tasks/
|
||||
называла слишком много: роадмап **весь** про разработку, и секция с таким именем
|
||||
не отличалась от остальных ничем.
|
||||
|
||||
**Секции «блокеры» в беклоге нет.** Блокер — это *состояние* (спринт не может
|
||||
**Секции «блокеры» в беклоге нет.** Блокер — это *состояние* (работа не может
|
||||
продолжаться ни одной задачей), а не полка: он живёт ровно до ответа человека, и
|
||||
записи в такой секции не успевают жить. Следы блокера остаются вопросами в
|
||||
файлах задач распущенного спринта. Постоянно пустая секция со старой семантикой
|
||||
файлах задач. Постоянно пустая секция со старой семантикой
|
||||
«разбираются пачками» противоречила бы правилу «блокер эскалируется немедленно»,
|
||||
поэтому `init` её заводить отказывается, а `check` о ней говорит. **Проекту,
|
||||
который переезжает с такой секцией, её надо удалить** — это единственное место,
|
||||
где это сказано.
|
||||
|
||||
**Задача живёт в одном индексе за раз.** Взята в спринт — строка переезжает из
|
||||
`BACKLOG.md` в `SPRINT.md`; вышла — обратно. Файл в `items/` при этом **не
|
||||
двигается**: он и есть запись, индексы лишь показывают, где она числится.
|
||||
**Запись живёт в одном индексе за раз.** Индексов два, и выбирает между ними
|
||||
тип: цель в роадмапе, задача в беклоге. Сменился тип — строка переезжает
|
||||
(`edit --type`). Файл в `items/` при этом **не двигается**: он и есть запись,
|
||||
индексы лишь показывают, где она числится и в каком порядке стоит.
|
||||
|
||||
**Порядок строк в беклоге — приоритет**, и он единственное, чего в файле нет
|
||||
(правило 4). Отсюда следствие для всякой машинной правки индекса:
|
||||
восстановленная или перенесённая строка встаёт **в конец своей секции**, и
|
||||
скрипт об этом говорит. Молчаливая вставка выдала бы машинную позицию за
|
||||
решение человека — а решение это его.
|
||||
|
||||
**У сделанной задачи записи не остаётся** — файл и строка удаляются (`close
|
||||
--implemented`). Ей хватает коммита и документации проекта; вторая запись была
|
||||
бы вторым домом для того же факта. Вопрос «что было в спринте N» отвечается
|
||||
даром: `SPRINT.md` лежит под git, `git log -p tasks/SPRINT.md` отдаёт историю
|
||||
всех наборов без отдельного журнала.
|
||||
бы вторым домом для того же факта. Вопрос «что было сделано и когда» отвечается
|
||||
даром: индексы лежат под git, а закрытие коммитится отдельным коммитом учёта —
|
||||
`git log -p tasks/BACKLOG.md` отдаёт историю без отдельного журнала.
|
||||
|
||||
**У достигнутой цели запись остаётся, и это единственное исключение.** Файл
|
||||
удаляется так же, а строка переезжает в секцию `Готово` с датой. Причина в том,
|
||||
@@ -152,7 +170,6 @@ tasks/
|
||||
stateDiagram-v2
|
||||
state "BACKLOG.md — что берут" as B
|
||||
state "ROADMAP.md — подо что берут" as P
|
||||
state "SPRINT.md — набор спринта" as S
|
||||
state "REJECTED.md — ушла без реализации" as R
|
||||
state "записи нет — реализована" as D
|
||||
state "ROADMAP.md, «умеет» — цель достигнута" as A
|
||||
@@ -161,12 +178,9 @@ stateDiagram-v2
|
||||
[*] --> P: add --type goal
|
||||
B --> P: edit --type goal --section
|
||||
P --> B: edit --type feature|fix|chore|research --section
|
||||
B --> S: sprint take
|
||||
S --> B: sprint drop --reason
|
||||
S --> D: close --implemented
|
||||
B --> D: close --implemented
|
||||
P --> A: close --implemented
|
||||
B --> R: close --reason
|
||||
S --> R: close --reason
|
||||
P --> R: close --reason
|
||||
D --> B: reopen --reason
|
||||
R --> B: reopen --reason
|
||||
@@ -247,7 +261,7 @@ stateDiagram-v2
|
||||
**поле меты `Тип` первой строкой**; эмодзи в заголовке H1 от него производна, её
|
||||
ставит `add` и чинит `check --fix`.
|
||||
|
||||
| Тип | Обязательные разделы | Цель | В спринт | Устав |
|
||||
| Тип | Обязательные разделы | Цель | В работу | Устав |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 🎯 `goal` | `Завершение` | — | нет | [task-goal.md](references/task-goal.md) |
|
||||
| ✨ `feature` | `Затрагивает`, `Критерии приёмки` | **обязательна** | да | [task-feature.md](references/task-feature.md) |
|
||||
@@ -270,14 +284,14 @@ stateDiagram-v2
|
||||
незаполненности** — «первый, второй или третий вопрос теста готовности не
|
||||
отвечается», — а состояние типом быть не может: оно меняется по мере того, как
|
||||
запись дописывают, а тип меняют командой. Теперь это состояние называется честно:
|
||||
`research` без раздела «Вопрос» — **сырьё**. В спринт не берётся ровно как
|
||||
`research` без раздела «Вопрос» — **сырьё**. В работу не берётся ровно как
|
||||
прежняя идея, лежит в конце своей категории и отбирается `list --raw`.
|
||||
|
||||
Словарь **закрыт**. Открытый разъедется на синонимах — `bug`, `bugfix`, `fix`,
|
||||
`defect`, — и отбор по типу перестанет отвечать на свой единственный вопрос. Ни
|
||||
один тип не подходит — это сигнал, что в задаче их два и её надо разделить.
|
||||
|
||||
**Требуется тип там, где по нему принимают решение:** `sprint take` без типа
|
||||
**Требуется тип там, где по нему принимают решение:** `ready` без типа
|
||||
откажет, потому что не знает, каких разделов требовать. `check` о пропаже только
|
||||
**напоминает** — беклог, заведённый до появления типа, законен, и переоформлять
|
||||
его «заодно» здесь не просят.
|
||||
@@ -324,7 +338,7 @@ stateDiagram-v2
|
||||
делать, и какие границы это трогает: эндпоинт или команду, таблицу и миграцию,
|
||||
формат на диске, публичный тип пакета, внешний сервис. Перечень живёт разделом
|
||||
«Затрагивает» (форма — [references/task-format.md](references/task-format.md)) и
|
||||
требуется к взятию в спринт. Без него задача оценивается по объёму текста, а не
|
||||
требуется к взятию в работу. Без него задача оценивается по объёму текста, а не
|
||||
по объёму поверхности, — и оценка систематически занижена ровно там, где текст
|
||||
короткий, а границ много. Названы **границы**, а не то, как они изменятся: план
|
||||
реализации живёт в предложении об изменении, а не в задаче.
|
||||
@@ -373,7 +387,7 @@ python3 $tk move S --dir D --section S [--reason R] [--after S | --first]
|
||||
python3 $tk close S --dir D --reason R # в REJECTED.md + удалить (ушла без реализации)
|
||||
python3 $tk close S --dir D --implemented # просто удалить (реализована и закоммичена)
|
||||
python3 $tk reopen S --dir D --reason R # вернуть закрытую: приёмка не сошлась
|
||||
python3 $tk sprint start (--goal S | --no-goal) --dir D | take S… | drop S… --reason R | close [--dissolve --reason R]
|
||||
python3 $tk ready S… --dir D # схема типа выполнена — можно брать в работу
|
||||
python3 $tk init --dir D [--sections …] [--items …] [--backlog …] …
|
||||
python3 $tk adopt scan --from … | apply --plan … # разовая адаптация, references/adopt.md
|
||||
```
|
||||
@@ -397,7 +411,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
||||
заголовке ставит скрипт.
|
||||
|
||||
**Мутации правят файл и индексы заодно** — руками строку индекса или мету
|
||||
не пиши, зови `add`/`edit`/`move`/`close`/`sprint`. Смена заголовка, «зачем», типа,
|
||||
не пиши, зови `add`/`edit`/`move`/`close`/`reopen`. Смена заголовка, «зачем», типа,
|
||||
цели и **тегов** — это `edit`: он держит H1 (вместе с эмодзи), мету и индекс
|
||||
согласованными. Снятие тега — `--rm-tag` (после ответа на вопрос снимается
|
||||
`question`), смена цели — `--goal`, типа — `--type`; оба заменяют прежнее
|
||||
@@ -410,7 +424,12 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
||||
`move` двигает только внутри одного индекса и пишет причину. `--section` у
|
||||
`edit` работает **только** при таком переезде — иначе он отсылает к `move`,
|
||||
потому что смена секции без причины и есть тот дрейф, который потом никто не
|
||||
объяснит. Задача в наборе спринта тип не меняет вовсе: сперва `sprint drop`.
|
||||
объяснит.
|
||||
|
||||
**`move --after <слаг>` и `move --first` — это и есть расстановка приоритета.**
|
||||
Порядок строк в секции значим (правило 4), и двигают его только этой командой:
|
||||
руками поправленная строка не оставляет причины, а причина здесь и есть половина
|
||||
решения.
|
||||
|
||||
Тело задачи скрипт не трогает:
|
||||
`add` кладёт заголовок, мета-блок и шаблон с подсказками, тело дописываешь
|
||||
@@ -439,9 +458,9 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
||||
где по нему принимают решение. Такие записи идут в `НЕОДНОЗНАЧНО`, и тип им
|
||||
проставляет человек — `edit <слаг> --type …`.
|
||||
|
||||
**Что механизировано, а что нет.** У задачи, взятой в набор (`sprint take` и
|
||||
`check` по задачам спринта), проверяется схема её типа, и у каждой части своя
|
||||
глубина:
|
||||
**Что механизировано, а что нет.** Схему типа проверяет `ready` на входе в
|
||||
работу — там, где по ней принимают решение; `check` о недостающем только
|
||||
напоминает счётчиком «готово к взятию». У каждой части своя глубина:
|
||||
|
||||
- **тип** — жёстко: назван и из закрытого словаря;
|
||||
- **критерии приёмки** (`feature`, `fix`, `chore`) — число пунктов жёстко
|
||||
@@ -602,7 +621,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
||||
ровно там, где по нему отбирают, **и требует не тех разделов**: у брошенного
|
||||
`fix` останется «Воспроизведение», которого нечем заполнить;
|
||||
- **сырьё, у которого появился вопрос** — разведка обросла формулировкой, но
|
||||
раздел «Вопрос» так и пуст: она числится сырьём и в спринт не берётся.
|
||||
раздел «Вопрос» так и пуст: она числится сырьём и в работу не берётся.
|
||||
Записывается вопрос, и `check --fix` поднимает строку из конца категории;
|
||||
- **границы, названные вместо реализации** — «переписать хранилище на новый
|
||||
драйвер» в разделе «Затрагивает» это не граница, а замысел. Границы —
|
||||
@@ -691,6 +710,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
||||
## Чего этот скилл не делает
|
||||
|
||||
Не пишет код, не заводит спеки и предложения об изменении, не берёт задачу в
|
||||
работу — этим занимается пайплайн проекта. Не ведёт спринт и не проводит сессию
|
||||
между спринтами — это `session`. Не решает за пользователя, что важно. Не
|
||||
работу — этим занимается пайплайн проекта. **Не ведёт очередь:** что делать
|
||||
следующим и что перестало быть важным — скилл `groom`, а этот даёт ему операции.
|
||||
Не решает за пользователя, что важно. Не
|
||||
переоформляет существующие задачи «заодно»: правится то, чего касается операция.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Проект, где задачи уже как-то ведутся, и из имеющегося материала **выводится**
|
||||
заполненный каталог задач: цели, задачи, кладбище, индексы. Операция разовая —
|
||||
после неё проект живёт скиллами `tasks` и `session`.
|
||||
после неё проект живёт скиллами `tasks` и `groom`.
|
||||
|
||||
**Это часть приведения проекта к канону.** Раскладку `docs/` целиком ведёт скилл
|
||||
`av-dev-docs:canon`; он же зовёт этот сценарий на шаге «каталог задач», потому что
|
||||
@@ -94,13 +94,15 @@ python3 $tk adopt apply --plan tasks-adopt-plan.json \
|
||||
быть названо, иначе следующий агент примет пустой беклог за поломку.
|
||||
|
||||
`apply` печатает состояние по факту: сколько задач без цели (это **ошибки**
|
||||
`check`) и сколько без критериев (`check` их ошибкой не считает, но `sprint
|
||||
take` такую задачу не возьмёт). Закрывается это **порциями переоценки** — шаг 3
|
||||
скилла `session`, 5–8 задач за порцию: проставить цели, превратить «готово,
|
||||
когда» в критерии с оракулами, вынуть вопросы из прозы в раздел «Вопросы».
|
||||
`check`) и сколько без критериев (`check` их ошибкой не считает, но `ready`
|
||||
такую задачу не пропустит). Закрывается это **порциями груминга** — скилл
|
||||
`groom`, 5–8 задач за порцию: проставить цели, превратить «готово, когда» в
|
||||
критерии с оракулами, вынуть вопросы из прозы в раздел «Вопросы». Там же
|
||||
беклогу впервые назначается **порядок**: после адаптации его нет вовсе, а
|
||||
очередь и есть то, ради чего каталог заводят.
|
||||
|
||||
Готовность к первому спринту — не «`check` зелёный», а «есть 2–5 критериев хотя
|
||||
бы у набора под одну цель».
|
||||
Готовность к первой задаче — не «`check` зелёный», а «`ready` пропускает хотя бы
|
||||
верхние строки очереди».
|
||||
|
||||
## Чего адаптация не делает
|
||||
|
||||
@@ -109,7 +111,7 @@ take` такую задачу не возьмёт). Закрывается эт
|
||||
- **Не переписывает подписи ссылок.** `[docs/backlog](tasks/BACKLOG.md)` —
|
||||
цель поправлена, текст остался; это правится глазами, и таких мест немного.
|
||||
- **Не сочиняет критерии приёмки и не придумывает цели**, которых в материале
|
||||
нет. Придуманная цель хуже отсутствующей: под неё соберут спринт.
|
||||
нет. Придуманная цель хуже отсутствующей: под неё заведут задачи.
|
||||
- **Не трогает историю.** В коммитах старые слаги остаются, и это нормально.
|
||||
|
||||
## Доклад
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
переживает запись.
|
||||
- **Находка без свидетельства / низкой уверенности** → **сырьё**: `research`, у
|
||||
которого раздел «Вопрос» и есть недостающее свидетельство («при каких условиях
|
||||
это воспроизводится»). Не `fix`: без `Воспроизведения` его в спринт не
|
||||
это воспроизводится»). Не `fix`: без `Воспроизведения` его в работу не
|
||||
возьмут, и правильно — чинить нечего, пока непонятно, что ломается. Судьба
|
||||
сырья — штурм, где либо найдётся подтверждение, либо оно уедет в
|
||||
`REJECTED.md`.
|
||||
@@ -46,7 +46,7 @@
|
||||
устареть, выноси пользователю, а не заводи молча заново.
|
||||
4. **Разложи по целям — там, где цель нужна.** Большинство находок ревью это
|
||||
`fix` и `chore`, и **цель им не требуется**: они служат работоспособности, а
|
||||
не направлению, и в спринт входят помимо его цели. Придуманная им цель —
|
||||
не направлению. Придуманная им цель —
|
||||
ровно то враньё, от которого спасает тип.
|
||||
|
||||
Цель обязательна у находки, которая оказалась **новой возможностью**
|
||||
@@ -79,13 +79,13 @@
|
||||
Правило замены:
|
||||
|
||||
- **тяжёлая находка со свидетельством** → задача под ту цель, которой она
|
||||
угрожает, и **кандидат в ближайший набор**: серьёзность здесь превращается в
|
||||
довод при выборе цели следующего спринта, а не в уровень в файле. Довод
|
||||
записывается причиной в мете (`--reason`), иначе к моменту набора его
|
||||
никто не вспомнит;
|
||||
- **находка, ломающая уже идущий спринт**, — не интейк вовсе: см. правило
|
||||
вторжения в скилле `session`. В беклог она падает, только если врываться не
|
||||
положено;
|
||||
угрожает, и **кандидат на верх очереди**: серьёзность здесь превращается в
|
||||
довод при расстановке приоритета, а не в уровень в файле. Довод записывается
|
||||
причиной в мете (`--reason`), иначе к моменту груминга его никто не вспомнит.
|
||||
Саму строку интейк ставит в конец секции: очередь назначает человек;
|
||||
- **находка, которая не ждёт груминга вовсе** (необратимый ущерб, сломан общий
|
||||
станок), — не интейк: это работа прямо сейчас, а в беклог она падает, только
|
||||
если ждать всё-таки можно;
|
||||
- **низкая уверенность или нет свидетельства** → сырьё (`research` с пустым
|
||||
разделом «Вопрос»);
|
||||
- **мелочь** → строка в пакетный файл;
|
||||
|
||||
@@ -66,13 +66,14 @@
|
||||
той же целью. Если частям нужен общий заголовок — значит у них общая
|
||||
возможность, и её надо назвать целью, а не заводить временный тип.
|
||||
|
||||
## Когда декомпозиция случается посреди спринта
|
||||
## Когда декомпозиция случается посреди работы
|
||||
|
||||
Задача, которая **оказалась крупнее задачи**, распознаётся до того, как под неё
|
||||
заведено предложение об изменении: иначе его придётся выбрасывать. Она выходит
|
||||
из набора (`sprint drop … --reason "крупнее задачи"`), уходит на декомпозицию, а
|
||||
спринт продолжается остальными. Части заводятся сразу под той же целью, но в
|
||||
текущий набор **не добавляются** — набор заморожен.
|
||||
уходит на декомпозицию, а её строка возвращается в беклог с причиной
|
||||
(`move … --reason "крупнее задачи"`). Части заводятся сразу под той же целью, и
|
||||
**место в очереди им назначает человек**: машина поставит их в конец секции, а
|
||||
крупная задача редко распадается на что-то менее срочное, чем была сама.
|
||||
|
||||
## Мозговой штурм сырья
|
||||
|
||||
@@ -80,7 +81,7 @@
|
||||
тест «готова к взятию», потому что неясно, что именно делаем. Штурм проясняет —
|
||||
и это **generative-операция, а не applicative**.
|
||||
|
||||
Исход штурма и есть заполненный «Вопрос» (тогда разведку можно брать в спринт)
|
||||
Исход штурма и есть заполненный «Вопрос» (тогда разведку можно брать в работу)
|
||||
или набор задач с типами, которые из ответа следуют. Третий законный исход —
|
||||
`close --reason`.
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
| Допустимые сверх того | `Рамки`, `Вопросы` |
|
||||
| Поле места | **Категория** — полка домена беклога |
|
||||
| Цель (`goal:<слаг>`) | нет: цель — это возможность, а здесь её не появляется |
|
||||
| Индекс | `BACKLOG.md` → `SPRINT.md` |
|
||||
| Берётся в спринт | да |
|
||||
| Индекс | `BACKLOG.md` |
|
||||
| Берётся в работу | да |
|
||||
|
||||
## Адресат — разработчик, и это законно
|
||||
|
||||
@@ -49,12 +49,12 @@
|
||||
(«обновить зависимости и переписать сборку и убрать мёртвый код»). Не
|
||||
мерджится порознь — это несколько задач ([split.md](split.md)).
|
||||
6. **Цель не проставлять.** `chore` служит работоспособности, а не направлению,
|
||||
и в набор спринта входит помимо его цели. Работа по сопровождению проекта
|
||||
работоспособности, а не направлению. Работа по сопровождению проекта
|
||||
при этом видна в роадмапе — секцией `Сопровождение`, но целью не становится.
|
||||
|
||||
## Что видит машина, а что человек
|
||||
|
||||
`check` и `sprint take` смотрят на **наличие непустого** `Затрагивает` и на
|
||||
`check` и `ready` смотрят на **наличие непустого** `Затрагивает` и на
|
||||
**число** критериев — ровно то же, что у `feature`. Разница между типами здесь не
|
||||
в строгости проверки, а в том, **кому адресован ответ** на «что станет
|
||||
наблюдаемо иначе», — и это судит человек.
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
| Допустимые сверх того | `Рамки`, `Вопросы` |
|
||||
| Поле места | **Категория** — полка домена беклога |
|
||||
| Цель (`goal:<слаг>`) | **обязательна** |
|
||||
| Индекс | `BACKLOG.md` → `SPRINT.md` |
|
||||
| Берётся в спринт | да |
|
||||
| Индекс | `BACKLOG.md` |
|
||||
| Берётся в работу | да |
|
||||
|
||||
**Цель обязательна, и это единственный тип, у которого так.** Новая возможность
|
||||
и есть содержание цели: подходящей нет — либо она заводится, либо перед тобой не
|
||||
`feature`. `sprint take` без цели откажет.
|
||||
`feature`. `ready` без цели откажет.
|
||||
|
||||
## Алгоритм
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
## Что видит машина, а что человек
|
||||
|
||||
`check` и `sprint take` смотрят на **наличие непустого** раздела `Затрагивает`,
|
||||
`check` и `ready` смотрят на **наличие непустого** раздела `Затрагивает`,
|
||||
на **число** критериев (меньше двух — отказ, больше пяти — замечание) и на цель.
|
||||
Наличие оракула проверяется **эвристикой** — словом «оракул» в пункте.
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
| Допустимые сверх того | `Рамки`, `Вопросы` |
|
||||
| Поле места | **Категория** — полка домена беклога |
|
||||
| Цель (`goal:<слаг>`) | необязательна |
|
||||
| Индекс | `BACKLOG.md` → `SPRINT.md` |
|
||||
| Берётся в спринт | да |
|
||||
| Индекс | `BACKLOG.md` |
|
||||
| Берётся в работу | да |
|
||||
|
||||
## `Воспроизведение` — раздел, которого нет у других типов
|
||||
|
||||
**Не воспроизводится — это `research`, а не `fix`.** Правило было записано и
|
||||
раньше, но проверять его было нечем, и «починки» без единого шага повторения
|
||||
уходили в спринт наравне с остальными. Раздел делает правило проверяемым: он
|
||||
уходили в работу наравне с остальными. Раздел делает правило проверяемым: он
|
||||
называет, **что сделать, чтобы расхождение проявилось, и что при этом видно
|
||||
вместо ожидаемого**.
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
(«ввод `а1` принимается по-прежнему»). Без него починка чинит одно и ломает
|
||||
соседнее.
|
||||
6. **Цель не выдумывать.** `fix` служит работоспособности, а не направлению, и в
|
||||
набор спринта входит помимо его цели. Придуманная цель — то же враньё, от
|
||||
работоспособности, а не направлению. Придуманная цель — то же враньё, от
|
||||
которого спасает тип.
|
||||
7. **Записать дефект в журнал** `docs/review.md` с пометкой «проскочил / пойман
|
||||
ревью». Проскочившие — проверочный набор для калибровки конвейера; пойманные с
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
## Что видит машина, а что человек
|
||||
|
||||
`check` и `sprint take` смотрят на **наличие непустого** `Воспроизведения` и
|
||||
`check` и `ready` смотрят на **наличие непустого** `Воспроизведения` и
|
||||
`Затрагивает` и на **число** критериев. Годность воспроизведения — человеку:
|
||||
шаги, по которым ничего не воспроизводится, машина от годных не отличает, и
|
||||
делать вид, что проверено больше проверенного, хуже, чем не проверять вовсе.
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
# 🐞 Не отбрасывать молча лишние символы в ходе
|
||||
|
||||
- **Тип:** fix
|
||||
- **Категория:** Ядро — вышла из спринта: остаток писал нерешённое в журнал
|
||||
- **Категория:** Ядро — вернулась из работы: остаток писал нерешённое в журнал
|
||||
- **Зачем:** ввод «а1б2» ходит в a1 — игрок не видит, что ошибся, и винит игру
|
||||
- **Теги:** goal:merge-robustness, sprint:2026-08-03
|
||||
- **Теги:** goal:merge-robustness
|
||||
|
||||
Разбор хода читает первые два символа и молча выбрасывает остаток строки.
|
||||
|
||||
@@ -63,11 +63,11 @@
|
||||
здоровье; годность формулировки смотрит агент `task-form`.
|
||||
- **Мета-блок** — список сразу после заголовка, **поле на строку**. Обязательны
|
||||
**тип** и **место**, причина после тире желательна (именно она объясняет,
|
||||
почему задача здесь оказалась — в том числе «вышла из спринта: …»), «зачем» и
|
||||
почему задача здесь оказалась — в том числе «вернулась из работы: …»), «зачем» и
|
||||
теги необязательны. Нераспознанные поля сохраняются: скрипт правит свои и не
|
||||
трогает чужие.
|
||||
- **Тип — первым полем.** Он решает, что у записи вообще может быть: какие
|
||||
разделы обязательны, нужна ли цель, берётся ли она в спринт, — и читается
|
||||
разделы обязательны, нужна ли цель, берётся ли она в работу, — и читается
|
||||
раньше всего остального. Словарь **закрыт**: `goal` | `feature` | `fix` |
|
||||
`chore` | `research`. Не подходит ни один — это сигнал, что в записи их два и
|
||||
её надо разделить.
|
||||
@@ -93,11 +93,11 @@
|
||||
| Тип | Поле | Значения | Что это |
|
||||
| --- | --- | --- | --- |
|
||||
| `goal` | **Секция** | `Запланировано`, `Направления`, `Сопровождение` | часть роадмапа: состояние очереди |
|
||||
| прочие | **Категория** | секции беклога проекта (`Ядро`, `Инфра`, …) | полка домена, в которую задача вернётся из спринта |
|
||||
| прочие | **Категория** | секции беклога проекта (`Ядро`, `Инфра`, …) | полка домена, на которой задача лежит |
|
||||
|
||||
Разные имена потому, что это **разные вещи**. У задачи поле переживает спринт:
|
||||
`sprint drop` возвращает её именно туда. У цели оно называет не полку, а место в
|
||||
очереди работ. Одно имя на два смысла их и смешивало; `check` называет
|
||||
Разные имена потому, что это **разные вещи**. У задачи это полка: куда её
|
||||
положили и куда вернут, если она уйдёт в работу и вернётся. У цели оно называет
|
||||
не полку, а место в очереди работ. Одно имя на два смысла их и смешивало; `check` называет
|
||||
несовпадение дрейфом, `check --fix` переименовывает.
|
||||
|
||||
Имя самого места принадлежит **заголовку индекса** — файл на него лишь
|
||||
@@ -142,7 +142,7 @@
|
||||
имя таблицы стабильно, номер последней миграции протухает молча. Пишется
|
||||
`таблица points и её миграция`, а не `миграция 0042`.
|
||||
|
||||
**Что из этого механизировано.** `check` и `sprint take` смотрят только на
|
||||
**Что из этого механизировано.** `check` и `ready` смотрят только на
|
||||
**наличие непустого раздела**. Полнота перечня машине не видна: границу, которую
|
||||
забыли назвать, она от отсутствующей не отличает. Раздела нет — отказ во взятии:
|
||||
оценивать нечем.
|
||||
@@ -158,7 +158,7 @@
|
||||
конкретизация вопроса «по чему видно, что закончено» из теста готовности ниже:
|
||||
там сказано «признак завершённости», здесь — «признак плюс чем проверяется».
|
||||
|
||||
**Что из этого механизировано.** `check` и `sprint take` считают пункты: меньше
|
||||
**Что из этого механизировано.** `check` и `ready` считают пункты: меньше
|
||||
двух — отказ («— работает» одной строкой больше не проходит), больше пяти —
|
||||
замечание, обычно это признак, что задача крупнее задачи. Наличие оракула
|
||||
проверяется **эвристикой** — словом «оракул» в пункте, — и потому даёт только
|
||||
@@ -205,8 +205,8 @@
|
||||
ответом. Затем снимается тег (`edit <slug> --rm-tag question`) и переписывается
|
||||
«зачем»: «Решено: …» на вопрос «зачем нужна эта задача» уже не отвечает.
|
||||
|
||||
**Порядок именно такой, потому что судит раздел, а не тег.** `sprint take`
|
||||
смотрит в непустой раздел и откажет взять задачу даже со снятым тегом, а `check`
|
||||
**Порядок именно такой, потому что судит раздел, а не тег.** `ready`
|
||||
смотрит в непустой раздел и откажет даже при снятом теге, а `check`
|
||||
на снятый тег при непустом разделе посоветует тег вернуть. Снять тег, не
|
||||
опустошив раздел, — значит закольцевать себя между двумя советами.
|
||||
|
||||
@@ -240,7 +240,7 @@
|
||||
`check` напоминает о нём у цели без задач замечанием — неразобранная цель
|
||||
законна и зелёного прогона не ломает; `check --fix` сам ставит его цели, у
|
||||
которой задачи есть, а цель с тегом и без задач — прямое приглашение закрыть.
|
||||
- Цель живёт в `ROADMAP.md` и **никогда** — в `BACKLOG.md` или `SPRINT.md`.
|
||||
- Цель живёт в `ROADMAP.md` и **никогда** — в `BACKLOG.md`.
|
||||
- **Достигнутая цель не исчезает.** `close <слаг> --implemented` удаляет файл и
|
||||
переносит строку в секцию `Готово` с датой:
|
||||
`- 2026-08-04 \`merge-order\` — Исход слияния не зависит от порядка доставки. …`
|
||||
@@ -277,33 +277,23 @@
|
||||
| Файл | Что отвечает | Секции |
|
||||
| --- | --- | --- |
|
||||
| `ROADMAP.md` | что приложение уже умеет и чего ещё не умеет | канонические и в этом порядке: `Запланировано`, `Направления`, `Сопровождение`, `Готово` (англ. `Planned`, `Directions`, `Operations`, `Done`) |
|
||||
| `BACKLOG.md` | что **можно взять** — только задачи | категории проекта (по умолчанию Ядро/Инфра) |
|
||||
| `SPRINT.md` | какая цель (или что её нет) и какой набор заморожен | одна: «Набор» |
|
||||
| `BACKLOG.md` | что **можно взять** — только задачи, **в порядке очереди** | категории проекта (по умолчанию Ядро/Инфра) |
|
||||
| `REJECTED.md` | что ушло без реализации и почему | — |
|
||||
|
||||
Шапку `SPRINT.md` пишет `sprint start` — **тем же мета-блоком, что у задачи**:
|
||||
поле на строку, `- **Цель:** [Заголовок](items/slug.md)`, `- **Начат:**` датой,
|
||||
`- **Спринт:**` слагом, которым метится урожай. У спринта без цели
|
||||
(`sprint start --no-goal`) поле «Цель» остаётся на месте и пишется прозой без
|
||||
ссылки — «не названа»: **«цели нет» и «цель потерялась» обязаны различаться**.
|
||||
Поэтому и признак «спринт идёт» — слаг, а не цель: слаг есть у любого спринта,
|
||||
без него нечем метить урожай. Прежняя форма (три поля одной
|
||||
строкой через `·`) читается по-прежнему и уходит сама: файл переписывается на
|
||||
следующем `sprint start` и очищается на `sprint close`.
|
||||
|
||||
Секции — **единственные заголовки `##` в индексе**: любой другой `##` в
|
||||
преамбуле проверка сочтёт секцией.
|
||||
|
||||
**Порядка «по важности» внутри секции беклога нет** — «что делать дальше»
|
||||
отвечает набор спринта. Единственный порядок, который есть, **производен от типа
|
||||
и заполненности**: **сырьё** (`research` без раздела «Вопрос») стоит в конце
|
||||
**Порядок строк внутри секции беклога значим: это очередь.** Первая строка — то,
|
||||
что делают следующим; назначает порядок человек на груминге, и двигают его
|
||||
`move --after` и `move --first`. Одно место из очереди изъято и **производно от
|
||||
типа и заполненности**: **сырьё** (`research` без раздела «Вопрос») стоит в конце
|
||||
своей секции, потому что его не берут, и между берущимся оно каждый раз требует
|
||||
открыть файл, чтобы это понять. Проверяет `check`, переставляет `check --fix`,
|
||||
и человек этот порядок не назначает — иначе он был бы приоритетом, которого
|
||||
здесь нет.
|
||||
|
||||
**Секции «блокеры» среди них нет.** Блокер — состояние, а не полка: он живёт до
|
||||
ответа человека, а следы остаются вопросами в файлах задач распущенного спринта.
|
||||
ответа человека, а следы остаются вопросами в файлах задач.
|
||||
Постоянно пустая секция со старой семантикой «разбираются пачками» противоречила
|
||||
бы правилу «эскалируем немедленно», поэтому `init` её не заводит, а `check`
|
||||
говорит о ней в чужом беклоге. Переезжаешь с такой секцией — удали её. В секции
|
||||
@@ -333,9 +323,6 @@ SKILL.md. Порядок закреплён потому, что `Готово`
|
||||
Поэтому отказ на второй задаче из пяти не оставляет первую переписанной при
|
||||
нетронутых индексах.
|
||||
|
||||
`SPRINT.md` и есть артефакт заморозки: без него набор существует только в
|
||||
контексте сессии, и нарушение заморозки ненаблюдаемо.
|
||||
|
||||
## `REJECTED.md`
|
||||
|
||||
Туда уходит задача, покинувшая беклог **без реализации**. Строку пишет
|
||||
@@ -361,15 +348,8 @@ SKILL.md. Порядок закреплён потому, что `Готово`
|
||||
|
||||
- `goal:<слаг>` — цель, которой служит задача. Обязателен **у `feature`**:
|
||||
новая возможность и есть содержание цели. У `fix`, `chore` и `research` его
|
||||
может не быть — они служат работоспособности, а не направлению, и в набор
|
||||
спринта входят помимо его цели.
|
||||
может не быть — они служат работоспособности, а не направлению.
|
||||
- `question` — в файле есть неразобранный раздел «Вопросы».
|
||||
- `sprint:<слаг>` — задача заведена в этом спринте; по нему отбирается первая
|
||||
порция разбора («урожай спринта»). **Ставится сам**: слаг спринта заводит
|
||||
`sprint start` (по умолчанию — дата начала, он же пишется в `SPRINT.md`), и
|
||||
`add` при открытом спринте помечает заводимое. Тег, который надо помнить
|
||||
ставить руками, не ставится никогда — а на нём висит правило «первая порция
|
||||
разбора — урожай прошедшего спринта».
|
||||
- `decomposed` — на цели: разложена на задачи (см. «Файл цели»).
|
||||
|
||||
Тега `kind:<род>` больше нет: род работы стал типом. Оставшийся в файле `check`
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
| Допустимые сверх того | — |
|
||||
| Поле места | **Секция** — часть роадмапа |
|
||||
| Цель (`goal:<слаг>`) | запрещена: цель и есть цель |
|
||||
| Индекс | `ROADMAP.md`, и никогда `BACKLOG.md` или `SPRINT.md` |
|
||||
| Берётся в спринт | нет — берутся её задачи |
|
||||
| Индекс | `ROADMAP.md`, и никогда `BACKLOG.md` |
|
||||
| Берётся в работу | нет — берутся её задачи |
|
||||
|
||||
Поле места у цели называется **«Секция»**, а не «Категория», и это не разнобой:
|
||||
у задачи оно называет полку домена, в которую она вернётся из спринта, а у цели
|
||||
у задачи оно называет полку домена, на которой она лежит, а у цели
|
||||
— часть роадмапа, то есть состояние очереди. Одно имя на два смысла их и
|
||||
смешивало.
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
**Место этому — переоценка на сессии, а не отдельный заход.** Отмена цели значит
|
||||
разбор всех её задач, а разбор задач и есть шаг 3 сессии
|
||||
([cadence.md](../../session/references/cadence.md), пункт 7). Отменять на ходу,
|
||||
(скилл `groom`, разбор «что перестало быть важным»). Отменять на ходу,
|
||||
между делом, — верный способ закрыть скопом то, что стоило перевесить.
|
||||
|
||||
## Что видит машина, а что человек
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
| Допустимые сверх того | `Рамки`, `Вопросы` |
|
||||
| Поле места | **Категория** — полка домена беклога |
|
||||
| Цель (`goal:<слаг>`) | нет |
|
||||
| Индекс | `BACKLOG.md` → `SPRINT.md` |
|
||||
| Берётся в спринт | да — **но только с заполненным «Вопросом»** |
|
||||
| Индекс | `BACKLOG.md` |
|
||||
| Берётся в работу | да — **но только с заполненным «Вопросом»** |
|
||||
|
||||
**Критериев приёмки у `research` нет, и это не поблажка.** Критерии в форме
|
||||
«оракул: тест» разведке натянуты: проверять нечего, пока ответа нет. Её приёмка
|
||||
@@ -39,13 +39,14 @@
|
||||
| | сырьё | разведка |
|
||||
| --- | --- | --- |
|
||||
| Раздел `Вопрос` | пуст или отсутствует | заполнен |
|
||||
| `sprint take` | отказ | берёт |
|
||||
| `ready` | отказ | берёт |
|
||||
| Место в секции беклога | **конец**, `check --fix` сносит туда сам | среди прочих |
|
||||
| `tasks.py list --raw` | показывает | нет |
|
||||
|
||||
Порядка «по важности» в беклоге по-прежнему нет. Этот порядок **производен от
|
||||
типа и заполненности**, а не назначен человеком, — потому его и проверяет машина,
|
||||
и потому он не противоречит правилу «порядка нет, есть цель».
|
||||
Порядок строк в беклоге назначает человек — это приоритет (правило 4 скилла).
|
||||
Место сырья **из него изъято**: оно производно от типа и заполненности, а не от
|
||||
чьего-то решения, и потому его проверяет и чинит машина. Приоритетом оно не
|
||||
становится: сырьё не берут вовсе, и место в конце говорит именно это.
|
||||
|
||||
Сырьём заводится и **сырая функция**: «Подсказка следующего хода» — ещё не
|
||||
`feature`, потому что неизвестно, что именно делать. Работа над ней — думание, и
|
||||
@@ -67,14 +68,14 @@
|
||||
проход ревью обязан читать как условие, а не как замер.
|
||||
5. **Разложить исход на задачи** — если он их родил. Разведка кончается одним из
|
||||
трёх: заведены задачи, записано знание, отказ. **Отказ — полноправный исход**:
|
||||
«проверили, не проблема» экономит спринт.
|
||||
«проверили, не проблема» экономит работу.
|
||||
6. **Закрыть** — `close <слаг> --implemented`, когда ответ записан. Файл
|
||||
удаляется: запись ответа и есть след, второго не нужно. Ушла без ответа —
|
||||
`close --reason`, и строка уезжает в `REJECTED.md`.
|
||||
|
||||
## Что видит машина, а что человек
|
||||
|
||||
`check` и `sprint take` смотрят на **наличие непустых** разделов `Вопрос` и
|
||||
`check` и `ready` смотрят на **наличие непустых** разделов `Вопрос` и
|
||||
`Куда ляжет ответ`, считают сырьё отдельной строкой здоровья и держат его в конце
|
||||
секции. Годность вопроса — человеку: «вопрос это или тема» машина не различает,
|
||||
и `check` о годности молчит намеренно.
|
||||
|
||||
@@ -3012,7 +3012,7 @@ def cmd_adopt_apply(a: argparse.Namespace) -> int:
|
||||
print(f" задач, не собравших разделы своего типа: {len(unfit)} —"
|
||||
f" check это ошибкой не считает, но `ready` их не пропустит:"
|
||||
f" брать сегодня физически нечего")
|
||||
print(f" закрывается порциями переоценки по 5–8 задач (скилл session, шаг 3):"
|
||||
print(f" закрывается порциями груминга по 5–8 задач (скилл groom):"
|
||||
f" проставить цели, превратить «готово, когда» в критерии с оракулами,"
|
||||
f" вынуть вопросы из прозы в раздел. Готовность к первой задаче —"
|
||||
f" не «check зелёный», а «есть {CRITERIA_MIN}+ критериев хотя бы у набора"
|
||||
|
||||
Reference in New Issue
Block a user