From 8d8c1656e5dab91ad2a4bf309cbb980b54e28553 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 13 Aug 2026 14:26:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B6=D1=83=D1=80=D0=BD=D0=B0=D0=BB=20=D1=80?= =?UTF-8?q?=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B9:=20=D1=82=D0=B5=D0=BC?= =?UTF-8?q?=D0=B0=2067=20=E2=80=94=20=D1=86=D0=B5=D0=BB=D1=8C=20=D1=83?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B7=D0=B4=D0=BD=D0=B5=D0=BD=D0=B0,=20?= =?UTF-8?q?=D1=83=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=8F=D0=B2=D0=B8=D0=BB=D0=B0=D1=81=D1=8C=20=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=B4=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Р237–Р243 и С228–С233: почему цель была зонтиком над параллельными направлениями и почему у линейного списка работ его нет; почему «Готово» удалена, а не перенесена; почему стадия объявляется явно и почему её русское имя — «доработка», а не занятая «поддержка». --- decisions/67-goal-removed-project-stages.md | 116 ++++++++++++++++++++ decisions/README.md | 5 +- 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 decisions/67-goal-removed-project-stages.md diff --git a/decisions/67-goal-removed-project-stages.md b/decisions/67-goal-removed-project-stages.md new file mode 100644 index 0000000..274e200 --- /dev/null +++ b/decisions/67-goal-removed-project-stages.md @@ -0,0 +1,116 @@ +# 67. Цель упразднена, у проекта появилась стадия (2026-08-13) + +## Что было + +Учёт работ вёлся двумя индексами. `ROADMAP.md` отвечал на «что приложение умеет +и чего ещё не умеет» целями (тип `goal`), `BACKLOG.md` — на «что можно взять» +задачами; связь шла тегом `goal:<слаг>`, обязательным у `feature`. Модель +сложилась темой 19 и держалась до сих пор. + +Владелец назвал наблюдение: у его проектов две стадии. Сперва активная +разработка, где нужен **один список от базы к деталям**, чтобы построить +приложение целиком; потом сопровождение и расширение, где правки точечные, а +архитектура не меняется. Цель в обеих не понадобилась ни разу. + +Разбор подтвердил, что это не вкус, а свойство: **цель — зонтик над +параллельными направлениями**, она нужна там, где список работ нельзя выстроить +в один порядок и очередь идёт поперёк направлений (это и записано в теме 19: «цель +и приоритет — независимые оси»). У проекта на одного человека параллельных +направлений не бывает, и зонтик не стоял ни над чем. + +Заодно нашлось, что роадмап отвечал на свой вопрос наполовину: «чего ещё не +умеет» — это «что осталось в беклоге», то есть пересказ второго индекса. + +## Решено + +**Р237. Тип `goal` и индекс `ROADMAP.md` упразднены.** Индекс остался один. +Вместе с целью ушли теги `goal:<слаг>` и `decomposed`, поле меты `Секция`, +раздел `Завершение`, команды `list --goal`, `edit --goal`, `edit --section` и +ключи `[tasks] roadmap`, `[tasks] completion_heading`. Тип `[epic]`, упразднённый +темой 19 в пользу цели, не вернулся: слишком крупный шаг дробится на шаги +помельче, и они встают в списке подряд — соседство и есть тот ответ, ради +которого заводили зонтик. + +Р78 («цель — возможность приложения, задача — шаг к ней») и Р80 («цель +обязательна не у всякой задачи») этим отменены, Р81 подтверждён. + +**Р238. Секция `Готово` удалена, а не перенесена.** Р77 заводил её потому, что +роадмап иначе показывал только «что осталось». Довод верен ровно для роадмапа: у +самого факта «что приложение умеет» есть два дома и без него — нормативное +поведение в `openspec/specs/`, а когда и в каком порядке оно появилось — +`git log` индекса, где закрытие лежит отдельным коммитом учёта. Третий дом +списком строк был бы дублем, который никто не сверяет. + +**Р239. Стадия проекта — новая ось: `build` и `support`.** Решает она **что +значит порядок строк беклога**: на стройке зависимость («раньше нельзя»), на +доработке важность («раньше лучше»). Из этого выведено остальное — сколько у +беклога секций, как его пополняют, что значит его опустошение и применим ли +груминг. + +Ось заведена потому, что стадии переворачивают два действующих правила скилла, а +не украшают их. Правило 1 («беклог гниёт с той стороны, где его пополняют») +оказалось правилом **доработки**: на стройке список пишется вперёд целиком, и +фильтр «не заводи то, чего не делаешь сейчас» запретил бы написать план дальше +первого шага. Правило 4 («приоритет назначает человек») на стройке половину +порядка не назначает, а **обнаруживает**: зависимость видна, а не выбрана. + +**Р240. На стройке секция беклога ровно одна.** Порядок там — зависимость, и +разложенный по полкам список перестаёт быть планом: два шага из разных секций уже +не сравнить. На доработке полки законны, потому что правки независимы. Проверяет +`check`; слить секции сам он не берётся — в каком порядке пойдут строки слитых +полок, знает только человек. + +**Р241. Стадия объявляется явно, молчание ответом не считается.** `init --stage` +обязателен, `check` без ключа `[tasks] stage` отказывает, `check --fix` его не +подставляет. Это тот же довод, что у С145: необязательное значение, которое всё +же решают, заводится парой «значение или явный отказ», иначе забытый ключ и +осознанный выбор неотличимы. Здесь он сильнее обычного: без стадии **нечем +прочитать индекс** — переставить строку значит на стройке сломать план, а на +доработке принять решение о важности. + +**Р242. Переход стадии — команда, а не правка конфига.** `tasks.py stage +support` переносит остаток беклога в первую новую секцию, правит «Категорию» в +файлах и говорит, что порядок с этого момента значит другое. Датой перехода +служит коммит: отдельного журнала ради одной строки не заводится. **Запретить +переход раньше времени скрипт не берётся** — «приложение построено» решает +человек, а не счётчик строк; `check` лишь напоминает о пустом беклоге стройки. + +**Р243. Русское имя стадии — «доработка», а не «поддержка».** Слово «поддержка» +уже запрещено домом [shared/operations.md](../av-dev/shared/operations.md) как +синоним «сопровождения»: в нём слышится помощь пользователю. Третье техническое +значение сделало бы его окончательно нечитаемым. Английское имя осталось +`support` — оно в идентификаторе, а идентификатор и есть дом. + +## Что из этого следует + +**С228. Груминг стал операцией одной стадии.** На стройке оба его вопроса +отвечены заранее: «что важно» — первая строка плана, назначенная зависимостью, а +«что перестало быть важным» возникает не порциями, а разом, при смене замысла, — и +тогда пересматривается план целиком. Порционный разбор там вреден: он вынимает +шаги из списка, порядок которого и есть его содержание. + +**С229. Тест декомпозиции ослаб на одной стадии и только на ней.** Условие +«части мерджатся независимо, порядок между ними значит план реализации» было +записано для беклога-очереди. Беклог стройки **весь** состоит из упорядоченных +зависимостью шагов, и «сперва А, потом Б» там не повод не дробить. Осталось общее +условие: каждая часть мерджится сама по себе. + +**С230. Залежалость считается только на доработке.** На стройке долгое лежание — +нормальное состояние шага, до которого не дошла очередь: он стоит там, где стоит, +по зависимости, и переоценивать его нечем. + +**С231. Стадия не влияет на метку ревью, глубину и тип задачи.** Клетка в +[перечне осей](../av-dev/shared/axes.md) названа пустой явно: изменение на стройке +ничем не проще того же изменения на доработке. Мысль «на стройке всё `small`, +приложения ведь ещё нет» разбивается о первый же шаг, кладущий схему хранилища. + +**С232. Запись типа `goal` машина не переводит.** `check --fix` снимает теги и +переименовывает поля, но во что превращается сама цель — в задачу или в ничто, — +решает человек, и она уезжает в `НЕОДНОЗНАЧНО`. Это то же правило, что у типа, +которого неоткуда взять. + +**С233. `adopt` получил стадию входным параметром.** Список пунктов одинаково +выглядит и планом стройки, и очередью правок; вывести стадию из материала +нельзя. Заодно нумерованные шаги источника перестали быть кандидатами в цели и +стали **порядком записей**: номер источника — единственное место, где чужая +раскладка называет зависимость. diff --git a/decisions/README.md b/decisions/README.md index cdb7a9f..00c8aae 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -6,8 +6,8 @@ Три сквозные нумерации, и они не пересекаются: - **Т** — требование: вход, который обязан быть удовлетворён. Живут здесь, ниже. -- **Р** — решение: что согласовано и почему. Р1–Р236 по темам в порядке журнала. -- **С** — следствие: что из решения вытекает. С1–С227, тоже сквозным счётом. +- **Р** — решение: что согласовано и почему. Р1–Р243 по темам в порядке журнала. +- **С** — следствие: что из решения вытекает. С1–С233, тоже сквозным счётом. Номер закреплён за записью навсегда: журнал описывает прошлые состояния и задним числом не переписывается. Отсюда и разнобой формы — ранние темы держат решения @@ -118,3 +118,4 @@ | 64 | [Три плагина слились в один: раскол платили, а не пользовались](64-three-plugins-merged.md) | 2026-08-13 | | 65 | [Перечень осей получил дом; две оси жили без владельца](65-axes-registry-home.md) | 2026-08-13 | | 66 | [`doc-canon` → `canon`: скилл формы вышел из семейства документов](66-canon-without-prefix.md) | 2026-08-13 | +| 67 | [Цель упразднена, у проекта появилась стадия](67-goal-removed-project-stages.md) | 2026-08-13 |