Что сделано
Новый файл packages/extension/test/architecture.test.ts — шесть статических проверок архитектуры, читающих исходники напрямую. Работает на node:test, новых зависимостей не требует.
| Проверка | Что ловит | Почему это тест, а не линтер |
|---|---|---|
| каждый файл объявляет слой | новый файл, забытый в карте слоёв | карта — это данные, а данные гниют: незадекларированный файл молча выпал бы из всех проверок направления |
| нет циклов в графе импортов |
import type-рёбра исключены |
type-only цикл легален в TS и стирается компилятором |
| нет восходящих рёбер между слоями L0–L5 | нижний слой знает о верхнем | type-only рёбра включены: времени они не стоят, но нижний слой называет верхний в сигнатурах — ровно та связанность, что запрещает docs/ARCHITECTURE.md
|
ядро не импортирует vscode/extension |
правило 1 docs/AGENTS.md
|
— |
нет обхода через import()/require()
|
иначе две проверки выше слепнут | статический граф такие рёбра не видит |
относительные импорты с явным .ts
|
правило 2 docs/AGENTS.md
|
node --test резолвит исходники напрямую |
eslint-plugin-import не взят намеренно: ему нужен резолвер под .ts-суффиксы и он всё равно не знает, в какую сторону можно смотреть из каждого слоя.
Почему это честный тест
Каждая проверка проверена на падение — нарушения вносились в код по одному, и падал именно нужный guard:
- восходящее ребро L1 → L2 (и отдельно type-only восходящее ребро);
- цикл
model.ts→edit.ts; -
import 'vscode'в ядре; - динамический
import(); - импорт без
.ts; - незадекларированный исходник.
Отдельно закреплено различие type-only рёбер: цикл разрешён, восходящее ребро запрещено.
Проверка
npm run check
ℹ tests 118
ℹ pass 118
ℹ fail 0
Было 112 тестов, стало 118 (+6). lint, format:check, typecheck — зелёные.
Замечания
- Тест попадает в существующий глоб
packages/extension/test/**/*.test.ts, правокpackage.jsonне требует. - CI-джоба
checkповторяетnpm run check; напоминаю, что она помеченаallow_failure: trueиз-за недоступности npm-реестра на раннерах.