docs: review document for #701

Issue: #701
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-28 21:51:00 +00:00
parent 8dcc1cad4e
commit 1606407107
+138
View File
@@ -0,0 +1,138 @@
# CODE-REVIEW-701-r1
- Issue: #701 «Канон: 26 расхождений документов между собой и с кодом, дубли правил, уроки одного случая»
- Трек: `show` · заход r1 · блокирующих циклов израсходовано 0 из 2
- Материал: `git log --oneline origin/dev..HEAD` → один коммит `8dcc1cad4edeed369f751d6b9fe96b798b4061e4`
поверх `origin/dev` @ `224d0106`; `git diff origin/dev...HEAD` — 21 файл,
232 вставки / 111 удалений
- Класс изменений: B (scripts, tests, `.github/workflows/_process.yml`) + C
(docs) — нет файлов класса A; задача инфраструктурная (PROCESS.md §1),
ТЗ не пишет — соответствует правилу
- Validate на этом SHA зелёный: https://github.com/Matysh/houseplan-card/actions/runs/36486646199
## Скоуп
Issue фиксирует 26 расхождений (D1–D26) между `PROCESS.md`, ролевыми
конспектами (`AUTHOR.md`, `REVIEWER.md`), `AGENTS.md`, `TESTING.md`,
`CONTRIBUTING.md`, `docs/DEVELOPMENT.md`, `docs/STATUS.md`, `docs/LESSONS.md`,
`docs/specs/README.md`, промптом `_process.yml` и исполняемым кодом
(`process-gate.mjs`, `validate-commit-provenance.mjs`, `mutation-registry.mjs`,
`entry-cost.mjs`, `gate-small.mjs`). Автор решает каждое расхождение «в пользу
кода, если код — действующее решение владельца, иначе чинится код» и добавляет
одно материальное поведенческое изменение: **документационный коммит (только
файлы класса C) больше не требует трейлеров `Issue:`/`User-Visible:`** — вынесен
общий модуль `scripts/change-classes.mjs`.
Работа обслуживает J6 «Keep the plan true as the home evolves» лишь косвенно —
это сам процесс поддержки продукта в согласованном состоянии, разрешено §1
AGENTS.md как «infrastructure» и подтверждено меткой `process` + `docs`.
## Как проверялось
Прочитан весь `git diff origin/dev...HEAD` (все 21 файл, все 15 hunks в
`PROCESS.md`), сопоставлен построчно с таблицей решений D1–D26 из комментария
автора. Ниже — таблица только по пунктам, где проверка потребовала выйти за
простое чтение диффа (код + тест + мутант); остальные D-пункты — точечные
правки текста, сверенные визуально построчно с диффом и не приведённые
отдельной строкой, чтобы не раздувать документ.
| D | Что проверено | Результат |
|---|---|---|
| D1 | `scripts/change-classes.mjs` — новый общий модуль; `validate-commit-provenance.mjs` импортирует `classify`, добавляет `isDocsOnlyCommit`; `process-gate.mjs` импортирует `classify` вместо локальной копии | код идентичен по регэкспам исходной копии из `process-gate.mjs` (diff — чистый вырез/вставка), порядок D→A→B→C сохранён |
| D1 (тест) | `isDocsOnlyCommit` доказана | `node --test test/commit-provenance.test.mjs` — зелёный; вручную применены оба мутанта реестра (`docs-only-commit-needs-trailers-again`, `docs-only-exemption-leaks-to-code`) — тест краснеет на обоих, рабочая копия восстановлена (`git status --porcelain` пуст) |
| D1 (хук) | `.githooks/commit-msg` зовёт `--staged`, значит `changedFiles` — реальный staged-список, а не пустой список из документного примера | прочитан `.githooks/commit-msg:13-14` |
| D1 (реестр) | `legacy/**` классифицируется как C с комментарием «только Markdown» | `find legacy -type f \| grep -v '\.md$'` → 0 файлов, подтверждено |
| D2 | `REVIEW_DOC_LIMIT = 6` в `process-gate.mjs` не менялся, только текст PROCESS.md подгонян под код | `grep -n REVIEW_DOC_LIMIT scripts/process-gate.mjs` совпадает с новой формулировкой «шесть документов одного вида» |
| D14 | Порядок чтения ревьюера в `_process.yml` (SCOPE→AGENTS→REVIEWER) совпадает с `ROUTES.reviewer.files` в `entry-cost.mjs` | тест `test/entry-cost.test.mjs` «#701 D14» зелёный; `node scripts/entry-cost.mjs` — совпадение подтверждено |
| Слова входа | Автор заявляет 5345→4703 (в тексте issue) / 5171→4703 (комментарий); коммит называет 5345→4703 | `node scripts/entry-cost.mjs` на HEAD даёт 4706 слов (расхождение в 3 слова — рероллы markdown/пробелы, не расхождение по существу) |
| Гейты | Юниты, задетые диффом | `node --test test/commit-provenance.test.mjs test/entry-cost.test.mjs test/process-digests.test.mjs test/pre-push-gate.test.mjs` — все зелёные (19+13+1+12 тестов) |
| Смоки | Есть ли исполняемый frontend-дифф | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` → «Исполняемого frontend-диффа нет … Browser-smoke этим диффом не выбираются — выбирать нечего» — прямой и однозначный ответ инструмента, ни один смок не пропущен |
| Трейлеры | `Issue:`/`User-Visible:` коммита | `git show -s --format=full HEAD` — `Issue: #701`, `User-Visible: no`; коммит сам содержит файлы класса B (scripts/tests/workflow), поэтому по новому правилу трейлеры обязательны и присутствуют — код применён к себе корректно |
## Что не проверял (и почему это ничего не пропускает)
- `npx tsc --noEmit`, `npm test` (полный), `npm run build` + сверка бандла —
не перегонял: Validate на этом же SHA `8dcc1cad` зелёный (ссылка выше),
бюджет раунда потрачен на чтение кода, как разрешает промпт ревью.
- `npm run golden:verify` — не запускался: метки `ci:golden` на issue нет,
дифф не касается `demo/golden/**` и рендера.
- `python -m pytest tests_backend -q` — не запускался: дифф не касается
`custom_components/**/*.py`.
- `npm run invariants -- --config <export>` — не запускался: дифф не меняет
геометрию модели ни ссылки на неё.
- Performance-профили — не запускались: не названы в AC/issue.
- Полный `npm run inventory` / полный прогон `mutation-gate.yml` (все шесты
шардов) — не запускался; автор заявляет локальный прогон диф-мутантов
«184 из 184» на `show`, где диф-мутанты не обязательны (REVIEWER.md, «Трек
show»): проверены точечно только два новых мутанта, относящихся к диффу
(см. таблицу выше), остальные 182 не переисполнялись — трек `show` этого не
требует.
- Не перечитывал все 26 точечных текстовых правок построчно вслух в этом
документе — свёл к таблице выше плюс визуальному сопоставлению с полным
диффом (`git diff origin/dev...HEAD -- PROCESS.md` и остальные файлы,
прочитаны целиком инструментом чтения, не по фрагментам).
## Находки
Нет находок уровня High или Medium. Ниже — один пункт уровня Low, снятый без
правки.
- **Low, снят.** Число слов входа автора в коммите/issue (5345/5171→4703) и на
измеренном HEAD (4706) расходятся на 2–3 слова. Причина, скорее всего, —
разница момента замера (до/после финальной правки одного предложения) или
особенность подсчёта `wc -w`-подобной функции на переносах строк; описанный
порядок величины (экономия ~640–700 слов, цель 3000 не достигнута, остаток
назван) не меняется, инструмент (`node scripts/entry-cost.mjs`) сам
показывает актуальное число при каждом запуске, а не текст документа —
учебная находка, не поведенческая. Снимаю без возврата автору.
## Что проверено и корректно
- Общий модуль классов (`change-classes.mjs`) устраняет дублирование логики
между `process-gate.mjs` и `validate-commit-provenance.mjs`, поведение не
изменилось для не-docs-only коммитов (тесты на классах A/B/D в
`test/commit-provenance.test.mjs` не тронуты и зелёные).
- Новое освобождение docs-only коммитов от трейлеров реализовано корректно:
пустой список файлов не считается docs-only («судить нечем»), любой файл вне
класса C возвращает коммит под старое правило, указанный трейлер всё равно
проверяется на валидность (тест `docs: typo\n\nIssue: #x` всё ещё краснеет).
Оба защитных инварианта доказаны мутантами и я лично воспроизвёл оба падения.
- Изменение маршрута автора (`docs/STATUS.md` убран из обязательного входа)
синхронно отражено в `entry-cost.mjs`, `AGENTS.md` и тексте PROCESS.md —
один источник, три места ссылаются, а не повторяют число.
- Переупорядочение маршрута ревьюера в промпте `_process.yml` (SCOPE→AGENTS→
REVIEWER) сопровождается новым тестом, который сверяет промпт и
`entry-cost.mjs` исполнением, а не на слово доверия.
- Автор честно перечислил недоделанное (п.4 «уроки → чек-листы подсистем» и
остаток до 3000 слов) как отдельное issue-предложение, а не спрятал в тексте.
- Одно число, видимое дважды в этом диффе (порог `REVIEW_DOC_LIMIT`), имеет
один источник — константу в `process-gate.mjs`; текст PROCESS.md её называет,
не дублирует.
- Риск, названный самим автором (файл, ошибочно отнесённый к классу C,
пройдёт без трейлеров), — не находка ревью: он не увеличился этим диффом
(тот же риск существовал и раньше в неявном виде, для `process-gate.mjs`),
а сведение классов в один модуль его уменьшает, а не создаёт.
## Раздел «Унаследовано» — не применяется
Это первый заход (r1) по этому issue; предыдущего раунда и материала нет.
## Вердикт
Зелёный. AC (D1–D26 плюс материальное изменение трейлеров) доказаны кодом,
тестами и исполнением мутантов там, где они заявлены; гейты, применимые к
этому диффу, зелёные или обоснованно не запускались; High/Medium находок нет.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/701-canon-consistency`, коммит `8dcc1cad4ede` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `18f1bb93547b43c41d19aecdcecb67e0fe35f3c2`
```
git log --all --format='%H %T' | grep 18f1bb93547b
```
- Тело issue: `592acae7c08ffffa64b312987ca7cff1e28155412a2c6531cb3e4eab0877eedf`
- Вердикт конвейера: `green` · High 0