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