Files
dev-skills/decisions/19-roadmap-is-state-not-queue.md
T
av bf6a173115 журнал решений: разложен по теме на файл, метки решений стали номерами
- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель;
- буквенные метки решений заменены сквозными Р1–Р234, следствия получили
  префикс С при прежних номерах: схема букв выродилась до пятибуквенных и
  сломалась — `АЕАКЛ` была занята и темой 53, и темой 65;
- 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер
  означал тему, а слово стояло «решение», формулировка исправлена.
2026-08-13 12:40:56 +03:00

9.9 KiB
Raw Blame History

19. Роадмап — состояние проекта, а не очередь работ (2026-08-04)

Что было

Основной инструмент владельца — роадмап и набор целей: «на каком этапе проект, что сделали и что осталось». Оценка идёт по поведению, а не по внутреннему устройству: что приложение уже может делать и чего ещё не может. Отсюда требование к формулировкам: цель отвечает на «что приложение будет делать», задача — на «что для этого нужно сделать».

Разбор показал, что инструмент отвечал ровно на половину этого вопроса.

Решено

Р77. Достигнутая цель из роадмапа не исчезает. close --implemented удалял у цели и файл, и строку — роадмап по построению показывал только «что осталось». Свидетельство нашлось в самом роадмапе healthlog: там руками заведена секция «Что уже пройдено» на двадцать строк прозы, и заканчивается она фразой «Эти звенья целями не заведены: закрытая цель записи не оставляет, ей хватает коммита и спеки». Обходной путь и его причина записаны рукой владельца. Теперь строка с датой переезжает в секцию достигнутого; файл удаляется по-прежнему.

Вторым домом поведения это не делает: нормативное поведение живёт в openspec/specs/, роадмап отвечает когда и в каком порядке оно появилось — другой вопрос. Ссылки на файл в строке нет намеренно: файла больше нет, а битая ссылка это законная ошибка check. Форма строки — как в REJECTED.md, и по той же причине.

Р78. Цель — возможность приложения, задача — шаг к ней. Заголовок цели отвечает на «что приложение будет уметь»: не «Работа со слиянием», а «Исход слияния не зависит от порядка доставки». Свойство поведения — тоже возможность: «сообщает о своём состоянии», «исход не зависит от порядка» — законные цели, переформулировки в функцию не требуют. Единственный настоящий чужак — работа над инструментом и процессом: на вопрос «что приложение будет уметь» она не отвечает и живёт в отдельной секции роадмапа.

Р79. Тест готовности задачи сменил защиту. Требование «что станет наблюдаемо иначе снаружи» переехало к цели. У задачи вместо него — какую строку «Завершения» своей цели она двигает. «Отрефакторить X» проваливает тест не потому, что невидим снаружи, а потому, что не находит строки, к которой относится. Побочная выгода: видно и обратное — строка «Завершения», к которой не относится ни одна задача, это незакрытая часть возможности. Отсюда требование к «Завершению» быть списком, а не абзацем: на абзац не сошлёшься.

Р80. Цель обязательна не у всякой задачи. Прежнее правило — «у каждой задачи должен быть goal:, иначе она не попадёт ни в один спринт» — было угрозой, а не аргументом, и заставляло операционную работу выдумывать себе направление. Граница проходит по роду работы: feature без цели не бывает (новая возможность и есть содержание цели), fix, chore и research живут без цели законно и входят в набор спринта помимо его цели. Это второй раз, когда род работы окупается, — и первый, когда он что-то определяет за пределами отбора.

Р81. Тип [epic] упразднён. Зонтик между целью и задачами не нужен: зонтиком стала цель, а слишком крупный шаг дробится на шаги помельче под ней. Замер: ноль употреблений на 97 записей двух живых проектов, при том что тип занимал место в словаре, тесте готовности, автомате переходов, split.md и трёх местах tasks.py.

Р82. Имена секций роадмапа — Готово / Запланировано / Направления / Разработка. Первый набор (умеет / строим / станок) прожил один заход и был признан неудачным. Из четырёх предложенных имён отвергнуто одно, и по проверяемой причине: окружение уже занято — в architecture.md это боевое окружение приложения, «где работает, что рядом, кто перезапускает», и одно слово в двух смыслах развело бы документы канона. Взято Разработка.

Принятый компромисс назван вслух: Готово слегка тянет обратно в трекерную рамку «состояние работы», тогда как секция про возможность. Перевесила читаемость с первого взгляда, а смысл несут заголовки целей внутри секции. Так же принято, что цель в Запланировано может быть уже наполовину построена: это очередь, а не «не начато», а «в работе» живёт в SPRINT.md.

Р83. Секции роадмапа канонические, секции беклога — нет. Разница выведена, а не назначена: у секций роадмапа есть семантика (достигнутое, очередь, долгое, не про продукт), в первую пишет сам close, и роадмап, названный по-своему, читался бы только своим автором. Секции беклога (Ядро, Инфра) семантики не несут — это полки. Поэтому check проверяет у роадмапа три вещи: состав закреплён (чужая секция — ошибка), все четыре обязаны быть, язык один на весь индекс; --roadmap-sections у init упразднён. Английский набор — Done | Planned | Directions | Tooling.

Проверено на том самом случае, ради которого правило и заводилось: секция «Что уже пройдено», которую healthlog вёл руками, теперь называется ошибкой поимённо.

Что из этого следует

С78. Ключа tasks.achieved_section не появилось. Секция достигнутого опознаётся по каноническому имени в любом из двух языков, и лишний knob не заводится: канонический состав отвечает на тот же вопрос надёжнее конфига.

С79. reopen цели снимает строку достигнутого. Иначе роадмап продолжает утверждать, что приложение умеет то, что вернулось в работу.

С80. Прозаический раздел в индексе — дрейф. Любой ## проверка считает секцией, поэтому «Что уже пройдено» и «Почему в таком порядке» в healthlog формально были двумя лишними секциями, куда могла уехать задача. При повышении они разбираются: звенья — строками в Готово, обоснование очереди — прозой внутри Запланировано.

С81. Правил стало пять, и нулевое — про смысл, а не про механику. «Цель — возможность, задача — шаг к ней» стоит перед правилами о гниении беклога и производности индексов, потому что из него следует, зачем эти механики нужны.