dma doctor
Мягкие сигналы эволюции для локальной работы — без падения CI.
dma doctor смотрит на тот же граф, что и check, но ищет сигналы роста, а не жёсткие нарушения. По умолчанию код выхода 0 — команду можно гонять хоть каждый коммит, CI не сломается.
Думайте о doctor как о «архитектурном линтере наперёд»: подсказывает, что пора вынести, промоутить или разделить — до того, как check начнёт ругаться.
Запуск
npx @derived-modular/cli doctor .
npx @derived-modular/cli doctor . --format json
npx @derived-modular/cli doctor . --format sarif
npx @derived-modular/cli doctor . --suggest # план удаления orphan-public
npx @derived-modular/cli doctor . --fix # удалить orphan public файлыТе же форматы вывода, что у check: human, json, SARIF.
doctor vs check
dma check | dma doctor | |
|---|---|---|
| Назначение | Жёсткие правила | Сигналы эволюции |
| Блокирует CI | Да (код выхода 1) | Нет (код выхода 0) |
| Повторяет rule ID из check | — | Нет |
| Когда запускать | CI, pre-push | Локально, раз в спринт |
Doctor не дублирует ошибки check. Если check красный — сначала чините check.
Сигналы
shared-candidate
Файл модуля импортируют 2+ других модуля.
В help — следующий шаг алгоритма размещения по текущему слою файла:
- в
features/→ promote вservices/<name>/public/(Placement #2) - в
services/→ оставить, если product flow, иначе вынести вshared/{ui,lib,…}(Placement #2–3) - в
shared/→ уже shared; следите, чтобы хелпер оставался переносимым (Placement #3)
Не поднимайте в shared автоматически — сначала поймите смысл кода.
stage-growth
Структура модуля отстаёт от размера. help привязывает фикс к colocation из placement:
- file-модуль (стадия 0) оброс соседними файлами с тем же basename-префиксом (например
checkout.tsx+checkout.store.ts) → папка иpublic/(Placement #4–5) - много файлов без сегментов → добавьте
ui/,model/,api/(Placement #4)
Порог по умолчанию — около 8 файлов (stage1FileCount).
Пример: stage-growth на checkout
До — стадия 0, один UI-файл, но рядом появился store с тем же префиксом:
features/
├── checkout.tsx
└── checkout.store.tsdma doctor → stage-growth: file-модуль checkout оброс соседний файл с префиксом checkout.
После — стадия 1:
features/checkout/
├── public/
│ └── checkout-page.tsx
├── checkout.store.ts
└── checkout.shipping.ts- Создайте папку
features/checkout/ - Перенесите UI в
public/checkout-page.tsx - Store и хелперы остаются internal;
public/импортирует их relative - Обновите импорты в корень композиции на
@/features/checkout/public/checkout-page npx @derived-modular/cli check .— зелёный;npx @derived-modular/cli doctor .—stage-growthдля checkout исчез
Если файлов станет ~8+ без сегментов — добавьте ui/, model/, api/ (стадия 2). См. Модули и public API.
dense-services
Подграф services/ выглядит плотным или глубоким. Пора делить горизонтально — домены, пакеты — а не добавлять новые вертикальные слои.
orphan-public
Файл в public/ никто не импортирует. Мёртвый контракт — удалите или сделайте внутренним.
--suggest / --fix могут удалить такие файлы только если в графе нет никаких импортеров (включая внутри модуля). Только single project root.
Типичный workflow
# утром
npx @derived-modular/cli check . # блокировка
# перед рефакторингом
npx @derived-modular/cli doctor . # что пора перестроить
# после крупного PR
npx @derived-modular/cli doctor . --format json > doctor.jsonНе ждите doctor в CI как блокировка
Сигналы субъективны: shared-candidate на здоровом services/*/public/* — норма. Используйте doctor для разговора в команде, не для блокировки слияния.
В CI doctor имеет смысл только как информационная задача (артефакт json для дашборда).
Связанные темы
- Эволюция кода — второе использование, promotion, триггеры
- dma check — жёсткие правила
- Обзор инструментов — гибридная модель