docs: review document for #699

Issue: #699
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-28 22:39:36 +00:00
parent c949e0bbc9
commit 48f6f2e6a7
+174
View File
@@ -0,0 +1,174 @@
# CODE-REVIEW-699-r3
Issue: #699 · этап: code · трек: show · заход: r3 · блокирующих циклов до этого раунда: 1/2
Материал раунда: `git log --oneline origin/dev..HEAD` / `git diff origin/dev...HEAD`,
вершина ветки `issue/699-ratchet-bands` = `4fa3c7977ebbd11907364af626f978deec790aa5`.
Validate на этом SHA — success (run 36491631358). Рабочая копия уже на этом SHA;
`git fetch`/`checkout` не делал.
Предыдущий раунд: r2, документ `docs/reviews/CODE-REVIEW-699-r2.md`, материал
`23aca8a987142633c6f0c7522538d6601aa942d9`, вердикт **зелёный** (High 0, Medium 0).
## Почему r3, если r2 был зелёным
Пока шло ревью r2, `dev` продвинулся на 17 коммитов (влиты #696–#698, #701,
#702). Владелец опубликовал кандидат `4fa3c797` как ребейз того же дерева на
новый `dev@e1700757` и сам заявил: «Дифф изменился при ребейзе… материал ревью
`23aca8a9` и кандидат `4fa3c797` дают разные patch-id: соседние правки в `dev`
изменили содержимое патча» (issue-комментарий 22:18:47, ссылка на §2.10, #492).
Зелёный вердикт цикл не тратит, но материал под ним умер (объекты `23aca8a9` и
дерево `d7500b073db5` не резолвятся в этом дереве — ожидаемо после ребейза,
`git cat-file -t` возвращает «not found», это не находка, см. REVIEWER.md
«Повторный раунд»), поэтому конвейер честно открыл новый заход, а не подтянул
старый вердикт под новый SHA (#312).
**Проверка гипотезы «дифф на самом деле не изменился».** Я не могу сравнить
деревья байт-в-байт (старые объекты собраны сборщиком мусора), поэтому сверил
по содержимому: прочитал целиком `git diff origin/dev...HEAD` (19 файлов,
856+/146-) и построчно сопоставил с описанием кода в r1/r2 (таблицы находок,
цитаты кода, номера тестов). Результат — по каждому файлу код и тесты
текстуально совпадают с тем, что описывали r1/r2:
`initialViewCeilingViolation`/`lazyGraphCeilingViolation` без ветки `shrank`,
`compareWithBaseline` с `METRIC_BANDS`, CLI `bundle-budget.mjs` с потолком
беты до `assertBundleBudget`, `mutation-registry-check.mjs` — `warned` вместо
`stale`, новый `scripts/ratchets.mjs` (`report`/`tighten`), шаг `tighten` в
`docs/DEVELOPMENT.md` («Prepare the candidate as usual», сразу после
`npm run bundle:release`) — ровно формулировка, которую цитировал r2. Значит
patch-id разошёлся не из-за смыслового отличия, а из-за смещения контекстных
строк при повторном ребейзе (PROCESS.md/докс, которые правили #701 и другие
соседи, лежат рядом с местом вставки #699). Разбор ниже — по этой дельте: она
не локальна формально (ребейз на ушедший вперёд `dev`, §2.10), поэтому я
перечитал файлы целиком и перепрогнал тесты сам (см. «Как проверялось»), а не
ограничился таблицей «чем закрыта» — но новых находок это не даёт, потому что
менять было нечего.
## Скоуп
Не изменился с r1 (см. `docs/reviews/CODE-REVIEW-699-r1.md`, «Скоуп»):
инфраструктурная задача, файлов класса A нет, `src/**` не тронут. Двусторонние
храповики с нулевым запасом заменены на полосу над потолком последней беты
(строки двух ядер, gzip четырёх графов, шесть чисел монолита, лимит браузерных
мутантов из жёсткого — в ориентир); `scripts/ratchets.mjs` — инструмент
релиз-менеджера (`report`/`tighten`); шаг `tighten` закреплён в единственном
каноническом release-runbook (`docs/DEVELOPMENT.md`) — это и есть M1 из r1,
закрытый в r2. Оба открытых вопроса ТЗ решены владельцем (полоса ядра = 50,
лимит мутантов — ориентир) и реализованы теми же числами.
`User-Visible: no` на всех четырёх коммитах (`47bdf883`, `44d4ff4f`, `56ebddf3`
и двух документных `61feca1f`/`bc15c3c9`/`4fa3c797`) — верно, продуктовое
поведение (`src/**`) не меняется; changelog не тронут, и это корректно при
`no` (проверено — `git diff origin/dev...HEAD --stat -- docs/CHANGELOG.md
docs/CHANGELOG.ru.md` пуст). Трейлеры `Issue: #699` / `User-Visible: no`
подтверждены на всех трёх кодовых коммитах (`git show -s --format=... | grep`).
## Как проверялось
Дешёвые гейты подтверждены зелёным Validate на этом же SHA (`4fa3c797`, run
36491631358) — `typecheck`, `npm test`, `npm run build` + bundle-policy не
перегонялись повторно. Поверх этого, по диффу и лично мной на этом SHA:
| Гейт | Прогнан | Результат |
|---|---|---|
| `node --test test/ratchets.test.mjs test/core-file-budget.test.mjs test/monolith-metrics.test.mjs test/bundle-assets.test.mjs test/mutation-gate.test.mjs test/process-digests.test.mjs test/monolith-text-anchors.test.mjs` | да, лично | 133/133 ok |
| `node scripts/mutation-gate.mjs --check` | да, лично | зелёный; `browser guards: 200/200`; 3 предсуществующих WARN (не относятся к #699, те же, что в r1/r2) |
| Защитный AC M1 — «тест умеет падать» перепроверен на этом SHA, не только унаследован | да, лично, исполнением | заменил в `docs/DEVELOPMENT.md` `tighten` → `report` в той же позиции (патч мутанта `release-runbook-forgets-tighten`), `node --test --test-name-pattern="#699 r1 M1" test/ratchets.test.mjs` → **1 fail** (`assert.match` не находит `tighten` после `bundle:release`), откатил (`git checkout -- docs/DEVELOPMENT.md`), `git status --porcelain` — пусто |
| Построчное сопоставление `git diff origin/dev...HEAD` (19 файлов) с описанием кода в r1/r2 | да, лично, чтением | текст диффа совпадает с цитатами и таблицами r1/r2 файл за файлом — см. «Почему r3» выше |
| `git diff origin/dev...HEAD --stat -- docs/CHANGELOG.md docs/CHANGELOG.ru.md` | да | пусто — корректно при `User-Visible: no` |
| Трейлеры `Issue`/`User-Visible` на `47bdf883`, `44d4ff4f`, `56ebddf3` | да, лично | все три — `Issue: #699`, `User-Visible: no` |
| `docs/reviews/INDEX.md` (r1/r2 уже проиндексированы) | да, прочитал | строки #699 r1 (🟡, M1) и r2 (🟢) на месте, согласуются с документами |
**Не прогонялось и почему:** полный дифф-мутационный прогон (`mutation-gate.mjs`
с реальными патчами, 186 мутантов) — трек show, зелёный Validate на этом SHA,
структурная `--check` чистая, и содержимое диффа не изменилось с r1/r2, где
этот прогон уже проводился (186/186); браузерные смоки — тело issue их не
называет, диф не трогает `src/**`/`demo/`, `smoke-select.mjs` не запускался за
отсутствием сопоставимого диффа; `golden:verify`, `pytest tests_backend`,
`npm run invariants`, performance-профили — не применимы (нет рендера, Python,
геометрии; AC их не называют); не проверял исполнением реальный
`release:prerelease` в GitHub Actions — унаследовано из r1/r2 как непроверенное
(эта часть дельтой r3 не затронута); `npx tsc --noEmit`/`npm test` целиком/
`npm run build` с трёхсторонней сверкой бандла — не перегонял: зелёный Validate
на этом же SHA подтверждает дешёвые гейты без повтора.
## Закрытие раунда r1
| Находка | Чем закрыта | Где это видно |
|---|---|---|
| **M1**: `node scripts/ratchets.mjs tighten` не был в единственном каноническом release-runbook `docs/DEVELOPMENT.md`; единственное упоминание — предупреждение внутри `release:prerelease` уже в момент публикации. | Шаг `tighten` в чек-листе «Prepare the candidate as usual» сразу после `npm run bundle:release`, до `docs/RELEASE-NOTES.md`/публикации; тест `#699 r1 M1` пере-проверяет и наличие, и порядок; мутант `release-runbook-forgets-tighten`. Перепроверено мной на `4fa3c797`: мутант применён вручную → тест падает (1 fail) → откат чистый. | `docs/DEVELOPMENT.md:525-534` (`Prepare the candidate as usual` → `bundle:release` → `ratchets.mjs tighten (#699 …) commit them with the candidate` → `RELEASE-NOTES.md`); `test/ratchets.test.mjs:69-75`; `scripts/mutation-registry.mjs` — `release-runbook-forgets-tighten`. |
Низкая находка **L1** (r1, оркестрация `tighten` без автотеста) была снята
ревьюером в r1 с записью (проверено исполнением в изолированном worktree);
дельта r2 и r3 её не касаются.
## Унаследовано из r1/r2 (без повторной проверки по существу)
Симметричность полосы по обеим границам на всех трёх видах храповика (ядра,
gzip-графы, числа монолита), корректность реордера в CLI `bundle-budget.mjs`
(потолок беты проверяется до `assertBundleBudget`, один источник байт-каунта),
пять новых мутантов реестра + один перенацеленный (якоря найдены по одному
разу), согласованность `PROCESS.md §8`/`docs/TESTING.md` с кодом, «одно число —
один источник» у потолка initial View (`INITIAL_VIEW_GZIP_CEILING` в
`bundle-budget.mjs`, `ratchets.mjs` читает его же регэкспом) — всё это разобрано
полно в `docs/reviews/CODE-REVIEW-699-r1.md` (материал `709c5b8a38f4`) и не
затронуто дельтой r1→r2→r3 текстуально (см. «Почему r3» выше — построчное
сопоставление). Принимаю без повторного вывода, кроме того, что перепроверил
сам и назвал в таблице выше (юниты, `mutation-gate --check`, M1-мутант).
## Находки
Новых находок нет. High: 0, Medium: 0.
Формальный повод для r3 (смена patch-id при повторном ребейзе, #492) не
породил содержательного отличия: диф `origin/dev...HEAD` на этом SHA
текстуально совпадает с тем, что рецензировали r1 и r2, тесты и мутационный
гейт зелёные лично на этом SHA, а M1 остаётся доказуемо закрытым (мутант
всё ещё ловится).
## Проверено и корректно
- Продуктовый код (`src/**`) не тронут — задача инфраструктурная, `User-Visible:
no` верно на всех коммитах, changelog не трогается, и это правильно.
- Рабочая копия чистая до и после моей проверки мутанта (`git status
--porcelain` — пусто оба раза), файлов в репозитории я не создавал (документ
ревью пишется вне репозитория, в `$REVIEW_DOC`).
- Тесты, гейты и трейлеры на текущем SHA `4fa3c797` дают тот же результат, что
описывали r1/r2 на своих (уже нерезолвящихся) SHA — расхождения нет.
## Чего не проверял
- Полный дифф-мутационный прогон `mutation-gate.mjs` с реальными патчами (186
мутантов, 6 шардов) — не перегонял на этом SHA: он уже был выполнен в r1 на
байт-идентичном по содержанию диффе, трек show, Validate зелёный.
- Браузерные смоки — диф не трогает `src/**`/`demo/`, `smoke-select.mjs` не
запускался за отсутствием сопоставимого диффа.
- `golden:verify`, `pytest tests_backend`, `npm run invariants`,
performance-профили — не применимы (нет рендера, Python, геометрии; AC их не
называют).
- Исполнение реального `release:prerelease` в GitHub Actions (печатает ли
`--warn` на практике) — унаследовано из r1/r2 как непроверенное.
- `npx tsc --noEmit`, `npm test` целиком, `npm run build` с трёхсторонней
сверкой бандла — не перегонял: зелёный Validate на `4fa3c797` (run
36491631358) подтверждает дешёвые гейты без повтора.
## Вердикт
Формальный r3 без содержательной дельты: рёбейз сменил patch-id, но не код.
M1 из r1 остаётся закрытым и перепроверен исполнением на текущем SHA. Новых
находок нет. High: 0, Medium: 0 → зелёный, цикл не тратится.
---
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/699-ratchet-bands`, коммит `4fa3c7977ebb` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `3dfcbd4230f3cf2b19d814176b2b5887dbd30564`
```
git log --all --format='%H %T' | grep 3dfcbd4230f3
```
- Тело issue: `18b6f2dce7c2f914e9c4d61715360cb529fc34c87cbad12c2a646990fefcb724`
- Вердикт конвейера: `green` · High 0