# Ledger: explicit-interfaces (2026-09-11, поздний вечер) Решение владельца: вариант A — явные реализации по умолчанию, классы напрямую не вызываем (исключения: DTO, хелперы, экстеншены), тесты через интерфейсы, моки — NSubstitute, маркерные классы не используем (маркерные интерфейсы). ## Итог - Codemod `scripts/make_explicit.py` (идемпотентный): таблицы членов интерфейсов (многострочные сигнатуры), маппинг класс→интерфейсы включая partial-файлы, конвертация `public M(` → `IFoo.M(`. Применено: 161 член в 30 прод-файлах. - Исправления компиляторного цикла: недостающие using'и в partial-файлах (скрипт-фиксер), снят дефолт параметра в явной реализации `ITenantLimitStore.GetOrCreateAsync`, самовызовы `WTelegramSessionClient` квалифицированы `((ISessionClient)this)`, мусорный using в `LlmHttpClient`. - Тесты: 17 файлов перетипизированы с конкретных классов на интерфейсы (поля, tuple-деконструкции, var/target-typed new); DI-регистрации фейков → регистрация интерфейсных инстансов. - Маркеры: 10 классов → интерфейсы `IKanbanModule`, `ICardsModule`, `IPipelineModule`, `IDiscoveryModule`, `ISettingsModule`, `ITelegramModule`, `ITenantsModule`, `IContracts`, `IInfrastructure`, `ISharedKernel`; тесты на `IsInterface`. - NSubstitute 6.1.0 добавлен в 5 тест-проектов; `FakePasswordHasher` удалён, вместо него `Support/TestHashers.New()` (Substitute.For + детерминированная семантика «fake-hash:»). - Правила владельца зафиксированы в §11 код-стайла; план миграции оставшихся ~30 фейков — `backlog.md` (TD-TESTS-NSUBSTITUTE). ## Проверка - `dotnet build` 5 sln: 0 warnings / 0 errors. - Тесты: core 1340/1340, telegram 130/130, ai 52/52, ml 38/38, storage 9/9. - Коммиты: ed25c71 (явные реализации), 93e9100 (маркеры), далее — NSubstitute/доки.