форма записи: заголовок отвечает на вопрос своего типа

Обкатка скилла tasks на выдуманном проекте — консольные крестики-нолики
на JavaScript, каталог заведён с нуля тем же скриптом. Форма вылезла
раньше содержания, и правки все про неё.

Заголовок отвечает на вопрос типа записи, и форм три: цель —
утверждение о возможности, задача — глагол в неопределённой форме
(допускается «не» перед ним), идея — назывное, без обещания. Причина не
стилистическая: описательный заголовок называет состояние, а из
состояния не видно, чего от работы ждут — «Ничья объявляется, пока
клетки есть» одинаково читается как жалоба и как задание. Отсюда же
разница индексов: роадмап — список возможностей, беклог — список работ,
и перепутанные формы делают каждый похожим на другой.

Механизировано ровно то, что механизируется: check считает заголовки,
где первое слово не на -ть/-ти/-чь, и печатает число в блоке здоровья.
Замечанием на файл нельзя — эвристика грубая, а на 97 записях двух живых
проектов это поток одинаковых строк, после которого пропускают весь блок.

Годность формулировки судит отдельный агент task-wording, а не чек-лист
в скилле: сейчас формулировку пишет и проверяет один агент в одном
контексте, а самопроверка текста слабее всего там, где формулировка
казалась удачной при написании. Он ничего не правит — возвращает готовые
формулировки, и заголовок с «зачем» показываются человеку, потому что
по ним задачу выбирают. Ничего из того, что ловит tasks.py check, он не
трогает намеренно: это был бы второй дом для правила.

Заголовки секций — с прописной, после заголовка пустая строка, во всех
индексах. Канонические имена стали Готово | Запланировано | Направления
| Разработка (англ. Done | Planned | Directions | Tooling), сверка везде
по нижнему регистру, так что старые индексы читаются по-прежнему.
Отбивка живёт на записи, а не на вставке: через Plan.index проходит
каждая правка индекса, а мест вставки три.

Имя секции принадлежит заголовку индекса, файл на неё только ссылается.
Это разрешает единственную неоднозначность починки — расхождение в одном
регистре правится в пользу заголовка. Без него переезд на канон оставил
бы «Готово» в роадмапе и «готово» в каждом файле цели, и свести это было
бы некому. Регистр правится только у канонических секций: имена секций
беклога выбирает проект.

Обкатка нашла два дефекта, которых не находили ни линтеры, ни свои
проверки. Вставка в пустую секцию съедала отбивку перед следующим
заголовком — пропуск пустых строк теперь идёт только до первой непустой.
Мета, разорванная пустой строкой, теряла поля молча: check видел лишь
следствие («без рода работы») и советовал edit --kind, который дописывал
второе такое же поле. Поле меты в теле стало ошибкой с названной
причиной, и --fix её намеренно не чинит — какое из двух значений верное,
знает человек.

DECISIONS тема 20 (ЕЕЕ–ККК, следствия 82–85), changelog канона v3
пополнен двумя пунктами и двумя шагами переезда, TODO — два шага для
healthlog и jellybit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-04 19:06:54 +03:00
co-authored by Claude Opus 5
parent ef0183b06b
commit 0c8390d774
12 changed files with 493 additions and 75 deletions
+93 -10
View File
@@ -1407,27 +1407,27 @@ SSS: рубрика на узел без нового понятия порож
словаре, тесте готовности, автомате переходов, `split.md` и трёх местах
`tasks.py`.
**ГГГ. Имена секций роадмапа — `готово` / `запланировано` / `направления` /
`разработка`.** Первый набор (`умеет` / `строим` / `станок`) прожил один заход и
**ГГГ. Имена секций роадмапа — `Готово` / `Запланировано` / `Направления` /
`Разработка`.** Первый набор (`умеет` / `строим` / `станок`) прожил один заход и
был признан неудачным. Из четырёх предложенных имён отвергнуто одно, и по
проверяемой причине: **`окружение` уже занято** — в `architecture.md` это боевое
окружение приложения, «где работает, что рядом, кто перезапускает», и одно слово
в двух смыслах развело бы документы канона. Взято `разработка`.
в двух смыслах развело бы документы канона. Взято `Разработка`.
Принятый компромисс назван вслух: `готово` слегка тянет обратно в трекерную рамку
Принятый компромисс назван вслух: `Готово` слегка тянет обратно в трекерную рамку
«состояние работы», тогда как секция про **возможность**. Перевесила читаемость с
первого взгляда, а смысл несут заголовки целей внутри секции. Так же принято, что
цель в `запланировано` может быть уже наполовину построена: это очередь, а не
цель в `Запланировано` может быть уже наполовину построена: это очередь, а не
«не начато», а «в работе» живёт в `SPRINT.md`.
**ДДД. Секции роадмапа канонические, секции беклога — нет.** Разница выведена, а
не назначена: у секций роадмапа есть **семантика** (достигнутое, очередь, долгое,
не про продукт), в первую пишет сам `close`, и роадмап, названный по-своему,
читался бы только своим автором. Секции беклога (`ядро`, `инфра`) семантики не
читался бы только своим автором. Секции беклога (`Ядро`, `Инфра`) семантики не
несут — это полки. Поэтому `check` проверяет у роадмапа три вещи: состав закреплён
(чужая секция — ошибка), все четыре обязаны быть, язык один на весь индекс;
`--roadmap-sections` у `init` упразднён. Английский набор — `done` | `planned` |
`directions` | `tooling`.
`--roadmap-sections` у `init` упразднён. Английский набор — `Done` | `Planned` |
`Directions` | `Tooling`.
Проверено на том самом случае, ради которого правило и заводилось: секция «Что
уже пройдено», которую healthlog вёл руками, теперь называется ошибкой поимённо.
@@ -1442,8 +1442,91 @@ SSS: рубрика на узел без нового понятия порож
80. **Прозаический раздел в индексе — дрейф.** Любой `##` проверка считает
секцией, поэтому «Что уже пройдено» и «Почему в таком порядке» в healthlog
формально были двумя лишними секциями, куда могла уехать задача. При
повышении они разбираются: звенья — строками в `умеет`, обоснование очереди —
прозой внутри `строим`.
повышении они разбираются: звенья — строками в `Готово`, обоснование очереди —
прозой внутри `Запланировано`.
81. **Правил стало пять, и нулевое — про смысл, а не про механику.** «Цель —
возможность, задача — шаг к ней» стоит перед правилами о гниении беклога и
производности индексов, потому что из него следует, зачем эти механики нужны.
## 20. Форма записи: заголовок, секции, вычитка (2026-08-04)
### Что было
Обкатка обновлённого скилла на выдуманном проекте — консольные крестики-нолики
на JavaScript. Каталог задач заведён с нуля тем же скриптом: шесть целей, девять
задач, отказ, достижение цели, спринт. Смотрели три вещи: тексты, разделы, состав
задач.
Форма вылезла раньше содержания. Индексы вышли с секциями со строчной буквы и без
отбивки после заголовка — читается как список списков, а не как документ. А все
заголовки задач оказались **описательными**: «Лишние символы в ходе молча
отбрасываются», «Поле печатается одним куском кода», «Линтер и тесты гоняются
одной командой». Правило «задача отвечает на «что для этого нужно сделать»» в
скилле стояло с самого начала — но относилось к содержанию задачи, а не к её
заголовку, и потому не применялось там, где заголовок и есть всё, что видно в
списке.
### Решено
**ЕЕЕ. Заголовок отвечает на вопрос своего типа, и форм три.** Цель — утверждение
о возможности («Соперником может быть компьютер»); задача — глагол в
неопределённой форме, допускается «не» перед ним («Не отбрасывать молча лишние
символы в ходе»); идея — назывное, без обещания. Причина не стилистическая:
описательный заголовок называет **состояние**, а из состояния не видно, чего от
работы ждут — «Ничья объявляется, пока клетки есть» одинаково читается как жалоба
и как задание. В списке, где решают «брать или не брать», это разные вещи.
Отсюда же разница индексов: роадмап — список возможностей, беклог — список работ.
Перепутанные формы заголовков делают каждый из них похожим на другой.
**ЖЖЖ. Механизировано ровно то, что механизируется, — счётчиком, а не
замечанием.** `check` считает заголовки, у которых первое слово не оканчивается
на `-ть`/`-ти`/`-чь` (перед ним допускается «не»), и печатает **число** в блоке
здоровья. Замечанием на файл этого делать нельзя: проверка эвристическая, а
беклог, заведённый до правила, переоформляют не «заодно» — десятки одинаковых
строк научили бы пропускать весь блок.
**ЗЗЗ. Годность формулировки судит отдельный агент `task-wording`, а не чек-лист
в скилле.** Самопроверка текста слабее всего там, где формулировка казалась
удачной при написании, — а пишет и проверяет иначе один и тот же агент в одном
контексте. Агент читает пачку записей и возвращает **готовые формулировки на
замену**, ничего не правя сам; заголовок и «зачем» подставляются командой и
показываются человеку, потому что именно по ним задачу выбирают. Он намеренно не
проверяет ничего из того, что ловит `tasks.py check`: повторить машинную проверку
словами значит завести правилу второй дом.
**ИИИ. Заголовок секции — с прописной, после него пустая строка.** Во всех
индексах, включая секции беклога, имена которых выбирает проект: правило про
**оформление**, а не про имя. Канонические имена стали писаться с прописной
(`Готово` | `Запланировано` | `Направления` | `Разработка`, англ. `Done` |
`Planned` | `Directions` | `Tooling`), сверка везде идёт по нижнему регистру, так
что старые индексы читаются по-прежнему и поднимаются `check --fix`.
**ККК. Имя секции принадлежит заголовку индекса, файл на неё только ссылается.**
Это разрешает единственную неоднозначность починки: расхождение файла и заголовка
**в одном регистре** правится в пользу заголовка. Без этого шага переезд на канон
оставил бы `Готово` в роадмапе и `готово` в каждом файле цели — расхождение
безвредное, но вечное, потому что свести его было бы некому.
### Что из этого следует
82. **Отбивка живёт на записи, а не на вставке.** `spaced_sections` вызывается в
`Plan.index`, через который проходит **каждая** запись индекса. Чинить
отбивку в каждом месте вставки значило бы полагаться на то, что ни одного не
забыли, — а мест вставки три (`--first`, `--after`, в конец).
83. **Обкатка нашла два дефекта, которых не нашли ни линтеры, ни свои проверки.**
Вставка в пустую секцию съедала отбивку перед следующим заголовком; мета,
разорванная пустой строкой, теряла поля молча, а `check` видел только
следствие («без рода работы») и советовал `edit --kind`, который дописывал
**второе** такое же поле. Оба класса теперь названы: пропуск пустых строк
идёт только до первой непустой, а поле меты в теле — ошибка с названной
причиной, которую `--fix` намеренно не чинит.
84. **Пустой проект показывает форму хуже живого.** Чтобы увидеть достигнутую
цель, отказ, спринт и все четыре рода работы, проект пришлось поставить на
середину пути. Это довод в пользу того, чтобы обкатку вести на *состоянии*, а
не на *старте*: у старта половина формы не наблюдаема.
85. **Мелкая цель даёт две задачи, и это не повод её укрупнять.** У цели
«Соперником может быть компьютер» третья задача напрашивалась (выбор уровня
соперника), но не мерджится порознь: без сильного соперника выбирать не из
чего. Тест декомпозиции её отбил — частичный ответ на вопрос «не выродились
ли цели в ярлыки тем».