# 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. Правил стало пять, и нулевое — про смысл, а не про механику.** «Цель — возможность, задача — шаг к ней» стоит перед правилами о гниении беклога и производности индексов, потому что из него следует, зачем эти механики нужны.