Монолит: мёртвый код снят по noUnusedLocals, связность измеряется шестью числами и гейтом (#624)

Карточка и редакторский рантайм держали ≈380 неиспользуемых импортов, 56
мёртвых объявлений и дублей типов (warm-boot, LS_*, GLOW_*, debounce,
navigate, lruRead — копии карточки в рантайме) и 112 приватных членов
карточки, которых не читал никто — делегаты `_editorRuntimeOrThrow()._x()`,
оставшиеся от выноса #425, и аксессоры glow-состояния. Всё это снято; в 9
других файлах — по одиночной ошибке. Делегаты и поля, которых касаются
браузерные смоки (`card._x(...)`), оставлены и посчитаны отдельно.

Гейт `npm run lint:unused` (scripts/unused-locals-gate.mjs, в gate:small и
Validate после сборки): `tsc --noUnusedLocals` чист, кроме приватных членов
карточки из порта HouseplanEditorHostPort / `host.` (portPrivates) и членов,
которых зовёт харнесс (harnessPrivates); храповик по шести числам
scripts/monolith-metrics.mjs против scripts/monolith-baseline.json —
delegates 260→159, portMembers 350, hostRefs 4948, portPrivates 96,
harnessPrivates 107, bundleBytes 2 510 141→2 500 387. `npm run inventory`
печатает те же числа. Заморозка 54 тестов, читающих монолит как текст
(test/monolith-text-anchors.test.mjs); PROCESS.md §2.7 — правило.

Логический исходник для контрактных тестов (test/houseplan-source.mjs)
дописывает члены рантайма без делегата в карточке — контракт продукта не
зависит от наличия заглушки. Потолки ядер и initial gzip опущены на выигрыш
(292 000 → 290 400). Бандл пересобран, три копии синхронны.

Issue: #624
User-Visible: no
This commit is contained in:
Claude
2026-09-23 21:09:44 +03:00
parent 14e56c0399
commit 47469bab22
75 changed files with 1344 additions and 1796 deletions
+16
View File
@@ -263,6 +263,22 @@ S1-new → S2-analysis → S3-spec → S4-spec-review ⟲ → S5-ready →
fix-up. Серверный стопор — шаг слияния конвейера сверяет вершину ветки с
SHA материала ревью (допустим только собственный doc-коммит публикации
поверх) и при расхождении отменяет слияние с возвратом в `S6-in-progress`.
- **Контракты по монолиту — исполнением, не regex по тексту (#624).**
Новое утверждение о `src/houseplan-card.ts` или
`src/houseplan-editor-runtime.ts` доказывается экспортом функции и её
вызовом в `test-build`, а не поиском строки в исходнике: текстовый якорь
краснеет на переносе метода без единой регрессии, и это делает вынос дороже,
чем оставить монолит как есть. Список тестов, читающих монолит как текст,
заморожен (`test/monolith-text-anchors.test.mjs`, 54 файла на 23.09.2026) и
может только уменьшаться; новое имя в нём — находка ревью, а не запись в
список. Связность монолита измеряется шестью числами
(`scripts/monolith-metrics.mjs`: делегаты, члены порта, `host.`, приватные
члены порта и харнесса, байты `dist/`), база — `scripts/monolith-baseline.json`;
гейт `npm run lint:unused` (в `gate:small` и Validate после сборки) красит
рост любого из них и любой мёртвый код по `noUnusedLocals` вне порта и
харнесса. Снижение фиксируется тем же коммитом
(`node scripts/unused-locals-gate.mjs --update`); рост — только с записью в
issue задачи и правкой базы в том же коммите.
- **Выход:** очередь на пре-релиз либо возврат в «В разработке», не более
4 циклов (§4). Второй и последующие циклы разбираются по дельте (§2.10).