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

87 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 20. Форма записи: заголовок, секции, вычитка (2026-08-04)
## Что было
Обкатка обновлённого скилла на выдуманном проекте — консольные крестики-нолики
на JavaScript. Каталог задач заведён с нуля тем же скриптом: шесть целей, девять
задач, отказ, достижение цели, спринт. Смотрели три вещи: тексты, разделы, состав
задач.
Форма вылезла раньше содержания. Индексы вышли с секциями со строчной буквы и без
отбивки после заголовка — читается как список списков, а не как документ. А все
заголовки задач оказались **описательными**: «Лишние символы в ходе молча
отбрасываются», «Поле печатается одним куском кода», «Линтер и тесты гоняются
одной командой». Правило «задача отвечает на «что для этого нужно сделать»» в
скилле стояло с самого начала — но относилось к содержанию задачи, а не к её
заголовку, и потому не применялось там, где заголовок и есть всё, что видно в
списке.
## Решено
**Р84. Заголовок отвечает на вопрос своего типа, и форм три.** Цель —
утверждение о возможности («Соперником может быть компьютер»); задача — глагол в
неопределённой форме, допускается «не» перед ним («Не отбрасывать молча лишние
символы в ходе»); идея — назывное, без обещания. Причина не стилистическая:
описательный заголовок называет **состояние**, а из состояния не видно, чего от
работы ждут — «Ничья объявляется, пока клетки есть» одинаково читается как
жалоба и как задание. В списке, где решают «брать или не брать», это разные
вещи.
Отсюда же разница индексов: роадмап — список возможностей, беклог — список работ.
Перепутанные формы заголовков делают каждый из них похожим на другой.
**Р85. Механизировано ровно то, что механизируется, — счётчиком, а не
замечанием.** `check` считает заголовки, у которых первое слово не оканчивается
на `-ть`/`-ти`/`-чь` (перед ним допускается «не»), и печатает **число** в блоке
здоровья. Замечанием на файл этого делать нельзя: проверка эвристическая, а
беклог, заведённый до правила, переоформляют не «заодно» — десятки одинаковых
строк научили бы пропускать весь блок.
**Р86. Годность формулировки судит отдельный агент `doc-wording`, а не чек-лист
в скилле.** Самопроверка текста слабее всего там, где формулировка казалась
удачной при написании, — а пишет и проверяет иначе один и тот же агент в одном
контексте. Агент читает пачку записей и возвращает **готовые формулировки на
замену**, ничего не правя сам; заголовок и «зачем» подставляются командой и
показываются человеку, потому что именно по ним задачу выбирают. Он намеренно не
проверяет ничего из того, что ловит `tasks.py check`: повторить машинную
проверку словами значит завести правилу второй дом.
**Р87. Заголовок секции — с прописной, после него пустая строка.** Во всех
индексах, включая секции беклога, имена которых выбирает проект: правило про
**оформление**, а не про имя. Канонические имена стали писаться с прописной
(`Готово` | `Запланировано` | `Направления` | `Разработка`, англ. `Done` |
`Planned` | `Directions` | `Tooling`), сверка везде идёт по нижнему регистру,
так что старые индексы читаются по-прежнему и поднимаются `check --fix`.
**Р88. Имя секции принадлежит заголовку индекса, файл на неё только ссылается.**
Это разрешает единственную неоднозначность починки: расхождение файла и
заголовка **в одном регистре** правится в пользу заголовка. Без этого шага
переезд на канон оставил бы `Готово` в роадмапе и `готово` в каждом файле цели —
расхождение безвредное, но вечное, потому что свести его было бы некому.
## Что из этого следует
**С82. Отбивка живёт на записи, а не на вставке.** `spaced_sections` вызывается
в `Plan.index`, через который проходит **каждая** запись индекса. Чинить отбивку
в каждом месте вставки значило бы полагаться на то, что ни одного не забыли, — а
мест вставки три (`--first`, `--after`, в конец).
**С83. Обкатка нашла два дефекта, которых не нашли ни линтеры, ни свои
проверки.** Вставка в пустую секцию съедала отбивку перед следующим заголовком;
мета, разорванная пустой строкой, теряла поля молча, а `check` видел только
следствие («без рода работы») и советовал `edit --kind`, который дописывал
**второе** такое же поле. Оба класса теперь названы: пропуск пустых строк идёт
только до первой непустой, а поле меты в теле — ошибка с названной причиной,
которую `--fix` намеренно не чинит.
**С84. Пустой проект показывает форму хуже живого.** Чтобы увидеть достигнутую
цель, отказ, спринт и все четыре рода работы, проект пришлось поставить на
середину пути. Это довод в пользу того, чтобы обкатку вести на *состоянии*, а не
на *старте*: у старта половина формы не наблюдаема.
**С85. Мелкая цель даёт две задачи, и это не повод её укрупнять.** У цели
«Соперником может быть компьютер» третья задача напрашивалась (выбор уровня
соперника), но не мерджится порознь: без сильного соперника выбирать не из чего.
Тест декомпозиции её отбил — частичный ответ на вопрос «не выродились ли цели в
ярлыки тем».