роадмап — состояние проекта, а не очередь работ
Основной инструмент владельца отвечал на половину своего вопроса. Оценка идёт по поведению: что приложение уже может и чего ещё не может, — а close --implemented удалял у достигнутой цели и файл, и строку, так что роадмап по построению показывал только «что осталось». Свидетельство лежало в самом роадмапе healthlog: секция «Что уже пройдено» на двадцать строк прозы, руками, с припиской «Эти звенья целями не заведены: закрытая цель записи не оставляет». Теперь строка с датой переезжает в секцию достигнутого, файл удаляется по-прежнему. Вторым домом поведения это не делает: нормативное поведение живёт в openspec/specs, роадмап отвечает, когда и в каком порядке оно появилось. Ссылки на файл в строке нет — файла больше нет, форма как в REJECTED.md. Цель стала возможностью приложения, задача — шагом к ней: - заголовок цели отвечает на «что приложение будет уметь»; свойство поведения («сообщает о своём состоянии», «исход не зависит от порядка») — тоже возможность и переформулировки не требует; - «Завершение» — списком, а не абзацем: задача ссылается на его строку, и это новая защита от «отрефакторить X» вместо прежнего «наблюдаемо снаружи». Заодно видно обратное: строка, к которой не относится ни одна задача, — незакрытая часть возможности; - работа над инструментом и процессом на этот вопрос не отвечает и живёт в отдельной секции. Цель обязательна не у всякой задачи. Прежнее «иначе она не попадёт ни в один спринт» было угрозой, а не аргументом, и заставляло операционную работу выдумывать себе направление. Граница по роду: feature без цели не бывает, fix, chore и research живут без неё и входят в набор помимо цели спринта. Тип [epic] упразднён: зонтиком стала цель, а слишком крупный шаг дробится под ней. Ноль употреблений на 97 записей двух живых проектов. Секции роадмапа — умеет / строим / направления / станок, четыре вместо двух; имена приняты как временные и запаркованы (TODO 7). Имя секции достигнутого знает скрипт — docs/.pm.json, ключ tasks.achieved_section. reopen цели снимает строку достигнутого, круг проверен вживую. Всё дописано в версию 3 канона: она ещё нигде не выкачена. DECISIONS 19, YYY–ГГГ и следствия 78–81. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1348,3 +1348,82 @@ SSS: рубрика на узел без нового понятия порож
|
||||
«привести к одному виду перед сравнением»), несёт правило идентичности и
|
||||
потому `deep`. Одно слово в описании задачи попадает в разные ступени — это не
|
||||
противоречие, смотрят не на слово.
|
||||
|
||||
## 19. Роадмап — состояние проекта, а не очередь работ (2026-08-04)
|
||||
|
||||
### Что было
|
||||
|
||||
Основной инструмент владельца — роадмап и набор целей: «на каком этапе проект,
|
||||
что сделали и что осталось». Оценка идёт по **поведению**, а не по внутреннему
|
||||
устройству: что приложение уже может делать и чего ещё не может. Отсюда
|
||||
требование к формулировкам: цель отвечает на «что приложение будет делать»,
|
||||
задача — на «что для этого нужно сделать».
|
||||
|
||||
Разбор показал, что инструмент отвечал ровно на половину этого вопроса.
|
||||
|
||||
### Решено
|
||||
|
||||
**YYY. Достигнутая цель из роадмапа не исчезает.** `close --implemented` удалял
|
||||
у цели и файл, и строку — роадмап по построению показывал только «что осталось».
|
||||
Свидетельство нашлось в самом роадмапе healthlog: там руками заведена секция «Что
|
||||
уже пройдено» на двадцать строк прозы, и заканчивается она фразой «Эти звенья
|
||||
целями не заведены: закрытая цель записи не оставляет, ей хватает коммита и
|
||||
спеки». Обходной путь и его причина записаны рукой владельца. Теперь строка с
|
||||
датой переезжает в секцию достигнутого; файл удаляется по-прежнему.
|
||||
|
||||
Вторым домом поведения это не делает: нормативное поведение живёт в
|
||||
`openspec/specs/`, роадмап отвечает **когда и в каком порядке** оно появилось —
|
||||
другой вопрос. Ссылки на файл в строке нет намеренно: файла больше нет, а битая
|
||||
ссылка это законная ошибка `check`. Форма строки — как в `REJECTED.md`, и по той
|
||||
же причине.
|
||||
|
||||
**ZZZ. Цель — возможность приложения, задача — шаг к ней.** Заголовок цели
|
||||
отвечает на «что приложение будет уметь»: не «Работа со слиянием», а «Исход
|
||||
слияния не зависит от порядка доставки». **Свойство поведения — тоже
|
||||
возможность**: «сообщает о своём состоянии», «исход не зависит от порядка» —
|
||||
законные цели, переформулировки в функцию не требуют. Единственный настоящий
|
||||
чужак — работа над инструментом и процессом: на вопрос «что приложение будет
|
||||
уметь» она не отвечает и живёт в отдельной секции роадмапа.
|
||||
|
||||
**ААА. Тест готовности задачи сменил защиту.** Требование «что станет наблюдаемо
|
||||
иначе снаружи» переехало к цели. У задачи вместо него — **какую строку
|
||||
«Завершения» своей цели она двигает**. «Отрефакторить X» проваливает тест не
|
||||
потому, что невидим снаружи, а потому, что не находит строки, к которой
|
||||
относится. Побочная выгода: видно и обратное — строка «Завершения», к которой не
|
||||
относится ни одна задача, это незакрытая часть возможности. Отсюда требование к
|
||||
«Завершению» быть **списком**, а не абзацем: на абзац не сошлёшься.
|
||||
|
||||
**БББ. Цель обязательна не у всякой задачи.** Прежнее правило — «у каждой задачи
|
||||
должен быть `goal:`, иначе она не попадёт ни в один спринт» — было угрозой, а не
|
||||
аргументом, и заставляло операционную работу выдумывать себе направление.
|
||||
Граница проходит по роду работы: `feature` без цели не бывает (новая возможность
|
||||
и есть содержание цели), `fix`, `chore` и `research` живут без цели законно и
|
||||
входят в набор спринта помимо его цели. Это второй раз, когда род работы
|
||||
окупается, — и первый, когда он что-то определяет за пределами отбора.
|
||||
|
||||
**ВВВ. Тип `[epic]` упразднён.** Зонтик между целью и задачами не нужен: зонтиком
|
||||
стала цель, а слишком крупный шаг дробится на шаги помельче под ней. Замер: ноль
|
||||
употреблений на 97 записей двух живых проектов, при том что тип занимал место в
|
||||
словаре, тесте готовности, автомате переходов, `split.md` и трёх местах
|
||||
`tasks.py`.
|
||||
|
||||
**ГГГ. Имена секций роадмапа временные.** `умеет` / `строим` / `направления` /
|
||||
`станок` приняты как рабочие и признаны неудачными на месте — особенно `станок`
|
||||
(слово пришло из `CLAUDE.md`, где «общий станок» уже значит инструмент,
|
||||
врывающийся в спринт). Вопрос запаркован до отдельного захода.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
78. **Секция достигнутого — единственная, чьё имя знает скрипт.** Остальные
|
||||
берутся из заголовков индекса как есть; в эту `close` пишет сам, поэтому её
|
||||
имя живёт в `docs/.pm.json`, ключ `tasks.achieved_section`.
|
||||
79. **`reopen` цели снимает строку достигнутого.** Иначе роадмап продолжает
|
||||
утверждать, что приложение умеет то, что вернулось в работу.
|
||||
80. **Прозаический раздел в индексе — дрейф.** Любой `##` проверка считает
|
||||
секцией, поэтому «Что уже пройдено» и «Почему в таком порядке» в healthlog
|
||||
формально были двумя лишними секциями, куда могла уехать задача. При
|
||||
повышении они разбираются: звенья — строками в `умеет`, обоснование очереди —
|
||||
прозой внутри `строим`.
|
||||
81. **Правил стало пять, и нулевое — про смысл, а не про механику.** «Цель —
|
||||
возможность, задача — шаг к ней» стоит перед правилами о гниении беклога и
|
||||
производности индексов, потому что из него следует, зачем эти механики нужны.
|
||||
|
||||
Reference in New Issue
Block a user