Skip to content

Реестр критериев ядра — возможности, инварианты, гипотезы

Статус: рабочий реестр к ТЗ ядра (создан 14.07.2026). Пара к ТЗ ядра + API: ТЗ отвечает «как устроено», этот файл — «что ядро обязано закрывать и как это проверить». Каждая строка = проверяемый критерий. Колонка «Где в ТЗ» связывает с разделом ТЗ/спекой; «Статус»: ✅ закрыто в ТЗ · 🧪 гипотеза (требует подтверждения практикой) · ⬜ пробел (в ТЗ не отражено — кандидат на следующую ревизию). Новый критерий добавляется сюда тем же PR, что и правка ТЗ; пробелы закрываются ревизией контрактов (по образцу ревизии 14.07.2026).

1. Продуктовые критерии (зачем ядро существует)

#КритерийПроверкаГде в ТЗСтатус
1.1Контент-менеджер клиента собирает и публикует страницу из блоков без обращения в студиюнаблюдение на первом клиенте (метрика README)core: компоненты, build-order волна 3🧪
1.2Новый тип контента (вакансии, проекты) заводится в админке без кодадемо «вакансии» на playgroundcore: типы контента
1.3Новый корпоративный сайт поднимается из skeleton + профиль установки за часы, не днихронометраж пилотаroadmap фаза 1🧪
1.4Обновление клиентского сайта — минуты и обратимоcms:upgrade с бэкапом/health/откатом на пилотеupdate-center🧪
1.5Сайт без единого модуля (голое ядро) — полноценный корпоративный сайт: страницы, формы, SEO, менюplayground-профиль «минимум»core: состав
1.6Headless-режим: публичный фронт может быть отдельным приложением поверх /api/v1JSON-схема форм, дерево меню, страницы по slug — без Bladecore: API
1.7Один инсталл обслуживает парк: мультисайт/мультитенант подключаемы без переделки ядраконтрактные тесты измерений в обоих режимахcore: контекст

2. Инварианты надёжности (нарушение = инцидент)

#КритерийПроверкаГде в ТЗСтатус
2.1Сбой любого блока/виджета/слушателя/фильтра не роняет страницу — fallback, не 500контрактный тест barrier-рендераcore: крайние случаи
2.2Выключение/сбой любого модуля не роняет публичный сайттест деградации в cms-testingstandard §0
2.35xx допустим только при отказе самого ядра; деградация провайдеров — 200 + meta.degradedтесты по каждому provides-потребителюcore: API-конвенции
2.4Параллельное редактирование не теряет данные молча — optimistic lock, 409, диалогтест 409 + UX-проверка диалогаcore: крайние случаи
2.5Обновление обратимо: бэкап → maintenance → migrate → health → откат при красномпрогон пайплайна на playgroundupdate-center
2.6Рестор бэкапа + cms:postupgrade возвращает работоспособный сайт (индексы/кеши пересозданы)периодический рестор-тестcore: эксплуатация
2.7Событийная шина at-least-once: слушатели ядра идемпотентны, повтор — no-opтест двойной доставкиcore: крайние случаи
2.8Частичный отказ инфраструктуры (Redis недоступен) — сайт живёт без кеша, деградация скорости, не 500chaos-тест на playgroundcore: крайние случаи, core: ревизия №2 п. 1
2.9Переполнение диска (логи, медиа) детектится health-чеком до падения БДhealth-чек free-space с порогомcore: эксплуатация, core: ревизия №2 п. 2 (базовый чек — ядро, расширенные — cms/health)

3. Контент и блоки

#КритерийПроверкаГде в ТЗСтатус
3.1Черновик → preview (подписанный токен) → публикация → откат на любую ревизиюfeature-тесты ревизийcore: страницы
3.2Схема блока версионируется (_v), данные мигрируют лениво + батчемcms:blocks:migrate идемпотентенblock-contract
3.3Редактор «средней свободы»: клиент не может сломать дизайн (нет стилей на блоке)Q9; ревью темыdecisions Q9
3.4Контент переносим между инсталляциями (dev → prod): экспорт с hash-сверкой схемcms:export/cms:import манифестcontent-model: перенос
3.5Медиа: конверсии, webp/avif, «где используется», защита от удаления используемоготест блокировки удаленияcore: медиа
3.6Ревизии не растут бесконечно — политика хранения N последнихнастройка + джоба ретеншнаcore: эксплуатация
3.7Совместное редактирование в реальном времени (два редактора видят курсоры друг друга)🧪 не берём в 1.0: 409-диалог достаточен, пересмотр по жалобам клиентов
3.8Планируемая публикация ревизии (в дату) — зона модуля scheduled-publishing, ядро даёт только событие/API публикациитест модуляmodules/scheduled-publishing
3.9AI-ассистенция контента (генерация текста блока, alt) — вне ядра, кандидат cms/ai-contentopen-questions: кандидаты🧪

4. API и интеграции

#КритерийПроверкаГде в ТЗСтатус
4.1Единый конверт {data, meta} / {error: {type, code, …}}, машиночитаемые codeконтрактный тест конвертаapi-contract
4.2Keyset-пагинация везде; COUNT(*) — только по запросутест ?with_countapi-contract
4.3Idempotency-Key на мутациях с внешним эффектом; replay → тот же ответтест повтораapi-contract
4.4Депрекация: заголовок + OpenAPI, удаление только в мажорелинтер OpenAPI-диффаcore: API-конвенции
4.5OpenAPI-автоспека покрывает 100% эндпоинтов (включая модули)CI-гейтstandard §14
4.6Persistent-роуты переживают выключение модуля (RFC 8058)тест выключенияcore: API-конвенции
4.7Runtime-типы контента видны интегратору: JSON-схема полей типа по APIGET /api/v1/content-types/{type}/schemacore: API типов, core: ревизия №2 п. 3
4.8Batch-вызовы / bulk-канал JSONL для массовых операцийфаза 3, cms/import/cms/exportapi-lessons §8🧪
4.9GraphQL — не берём, пока нет потребителяbuild-order: не делать раньше

5. Производительность и масштаб

#КритерийПроверкаГде в ТЗСтатус
5.1Page-cache hit = 0 запросов к БД; miss ≤ 15контрактный тест бюджетаcore: производительность
5.2Настройки на горячем пути = 0 запросов (кеш групп)контрактный тестthree-axes: настройки
5.3Инвалидация только тегами по событиям; Cache::flush() запрещёнлинтер + ревьюperformance
5.4Персонализация не убивает кеш: 2 штатных режима (блочный/полностраничный с лимитом кардинальности)тест утечки кеша между сегментамиcore: персонализация
5.5Голое ядро на VPS 2 vCPU/4 ГБ держит корпоративный трафик (p95 < 300 мс без кеша)нагрузочный прогон на playground🧪 цифры зафиксировать после Pulse на пилоте
5.6Octane-совместимость кода ядра (без глобального состояния между запросами)смок под Octanebuild-order: не раньше времени🧪
5.7100+ блоков на странице рендерятся в бюджете (кеш областей/фрагментов)синтетический тестcore: крайние случаи
5.8Медленный внешний вызов не блокирует рендер (очереди; синхронно ≤ 2 с + fallback)стандарт §9, ревьюstandard §9

6. Безопасность и ПДн

#КритерийПроверкаГде в ТЗСтатус
6.1Все 5 границ входа фильтруются стандартизированными обработчиками ядраsecurity-гейты волнcore: безопасность
6.2Rich-text — двойной барьер; {!! !!} только studio; ReDoS-валидатор regexлинтер + тестыsecurity
6.3Секреты никогда не в БД/логах/телеметрии; settings-store их отвергает схемойтест схемы настроек, env-линтерcore: безопасность
6.4«Выгрузить всё по субъекту» и «забыть» — по всем модулям одной командойcms:privacy:export/forget --dry-runcore: PrivacyRegistry
6.5Смена пароля инвалидирует сессии и токенытест UserPasswordChangedcore: безопасность
6.6Брутфорс/перебор гасятся rate-limit + attack-monitor (обязателен в managed)playground-тест волны 6build-order волна 6
6.7RBAC покрывает парк-сценарии: клиентские роли ≠ studio; опасное — только studioматрицы ролей в ТЗ модулейcore: права
6.8Загружаемые файлы сканируются (ClamAV/аналог) до публикацииконтракт upload-scanner: карантин pending до вердиктаcore: безопасность, core: ревизия №2 п. 4; модуль-реализация — кандидат каталога
6.9CSP-заголовки и SRI для админки и публичной части — дефолт темы/ядрасмок заголовков; report-only → enforcecore: безопасность, core: ревизия №2 п. 5 (фильтр security.csp)
6.10Аудит действий админов (кто что менял) — модуль cms/audit, но события ядра достаточны для негопокрытие событийmodules/audit

7. Расширяемость и экосистема модулей

#КритерийПроверкаГде в ТЗСтатус
7.1Модуль расширяет всё через 5 каналов + реестры; правка ядра не требуется никогдаинвариант §0 стандарта, ревьюdata-exchange
7.2Контракты в cms/core-contracts semver-стабильны; breaking — только мажор с депрекациейCI-дифф контрактовstandard §3
7.3Новый provides-контракт вводится только ревизией ядра (реестр закрыт)ревью манифестовstandard §2
7.4/local-слой: точечные правки конкретного сайта без форка ядра/модулейдемо-override на playgroundextensibility
7.5Платформа знает о модуле всё из манифеста (декларативность §0.3)cms:doctor, cms:mapstandard §2
7.6Тема — тоже контракт: каскад резолва, theme.json → Tailwind, галерея блоковсмена темы из админки на playgroundtheme-contract
7.7Сторонний разработчик может написать модуль по докам, не заглядывая в код ядрапробный модуль по docs/module.md + стандартуdx-claude-code🧪 фаза 5
7.8Capability/permission-слой для будущего маркетплейса заложен (модуль объявляет, что ему нужно)манифест permissionssecurity: маркетплейс

8. Эксплуатация парка и DX студии

#КритерийПроверкаГде в ТЗСтатус
8.1cms:doctor --json диагностирует типовые поломки без чтения кодасценарии рассогласования волны 6core: компоненты
8.2Машинная карта системы (cms:map) — модули, версии, роуты, хуки — для агента и флит-дашбордаGET /admin/system/mapcore: API
8.3Health-агрегат ядра+модулей за ≤ 2 с, пригоден для Caddy/мониторингатест таймаутов чековcore: производительность
8.4Телеметрия парка: версии, health, p95, hit-rate — суточный пинг (прозрачный для клиента)fleet-dashboard фаза 4update-center
8.5Claude Code пишет 100% кода модуля по ТЗ + донору: петля DX воспроизводимафакт полигона (волны 0–24 собраны агентом)dx-claude-code
8.6Генераторы cms:make:* дают скелет модуля, проходящий composer test из коробкисмок генератораbuild-order волна 0
8.7Время диагностики инцидента на клиентском сайте ≤ 15 мин (ранбук + doctor + health)пост-инцидентные разборыcore: эксплуатация🧪
8.8Staging-копия клиентского сайта поднимается одной командой (для проверки обновлений)прогон cms:backup:clone-to-staging на playgroundmodules/backup, core: ревизия №2 п. 6

9. Гипотезы принятые (проверяются пилотом, могут изменить контракты)

#ГипотезаКак проверяемРиск, если неверна
9.1JSONB+GIN достаточно для типов контента до ~10⁵ записей — EAV не нуженнагрузочный тест выборок по полямпересмотр хранения (дорогой мажор) — content-model
9.2«Средней свободы» редактора хватает клиентам — запросов на стили на блоке не будет массовообратная связь первых 3 клиентовдавление в сторону Tilda-режима (Q9 пересмотр)
9.3Одна кодовая база ядра тянет и корпсайт, и (позже) e-commerce без форкапилот фазы 3 на реальном магазинерасщепление на профили ядра
9.4Path-repos + Satis + cms:upgrade достаточно для дистрибуции — свой транспорт не нуженэксплуатация парка фазы 2возврат к идее агента обновлений
9.5Blade + острова закрывают 95% фронтенд-потребностей корпсайтов (React-темы не нужны)первые клиентские темыревизия frontend-architecture
9.6Bус-фактор снят документацией: новый исполнитель (человек/агент) входит в проект за деньонбординг-тест на свежем агентеусиление docs/module.md-гейтов

10. Граница ядра: что в ядре, что в модуле

Тест на включение в ядро — все четыре «да» (иначе — модуль):

  1. Нужно каждому корпоративному сайту с первого дня (не «многим», а каждому).
  2. Нельзя доустановить позже без переделки данных/контрактов (ревизии, измерения locale/city/site, движок полей — ретрофит дороже включения).
  3. На это опираются контракты: минимум два модуля из разных доменов используют способность через реестр/сервис ядра.
  4. Не тянет внешних зависимостей (API третьих сторон, тяжёлые бинарники, платные сервисы) — внешнее всегда за provides-контрактом в модуле.

Обратные признаки (любой — почти наверняка модуль): нужен не всем · внешний API/тариф · свой жизненный цикл данных (журналы с ретеншном, подписчики) · доменная логика (коммерция, маркетинг) · заменяемая реализация одной способности (поиск, капча, оплата).

Графовые критерии (проверяемые по манифестам — граф зависимостей): ядро не может требовать модуль — понадобилась стрелка ядро → модуль, значит способность спроектирована неверно (в ядре остаётся контракт, реализация уезжает в модуль); потребители из ≥ 2 разных доменов — аргумент за контракт в ядре, потребители одного домена — это хаб домена (commerce-orders, integrations-bus), а не ядро; у хаба с in-degree ≥ 5 дисциплина изменений — как у ядра (deprecation-окно, мажор с миграцией потребителей), но в ядро он от этого не переезжает.

Разбор пограничной зоны (паттерн везде один: ядро владеет точкой расширения и минимальной реализацией, модуль — расширенной/заменяемой):

СпособностьВ ядреВ модулеМотив
ПоискPG tsvector + GET /searchcms/search (Meilisearch/Typesense) через search-providerбазовый поиск нужен всем; движок — тяжёлая зависимость
РедиректыRedirectService + таблица + админ-CRUD— (модули только регистрируют)«изменён URL → 301» — целостность SEO каждого сайта
Sitemap/robotsгенерация + SitemapRegistryмодули регистрируют свои URLконтракт, на который опираются ≥5 модулей
ПДнPrivacyRegistry + cms:privacy:* + consent_at формcms/consents (реестр согласий, версии текстов, отчёты РКН)каскад «забыть» обязан работать и без модуля
Здоровье/system/health агрегат + таймаутыcms/health (расширенные чеки, алерты, эскалация)эндпоинт нужен мониторингу с первого дня
Медиамедиатека + конверсии + hook скана загрузокcms/storage-s3 (storage-backend), антивирус-модуль (контракт upload-scanner введён ревизией №2)локальный диск — каждому; S3/ClamAV — внешнее
Emailотправка через .env-транспорт (уведомления ядра)cms/transport-providers (фейловер, suppression), cms/email-templates (версии, редактор)письмо о лиде должно уйти и на голом ядре
Мультиязычностьизмерение locale в данных/кеше/RequestContext, i18n строк админкиcms/multilang (переводы контента, hreflang, fallback-цепочки UI)ретрофит измерения невозможен; UI переводов нужен не всем
Мультисайт/городизмерения site_id/city_id (nullable) вездеcms/multisite, cms/multicity (резолв, справочники, домены)то же правило измерений
Защита формCSRF/honeypot/rate-limit/consent_atcms/antispam (капчи через captcha-provider, скоринг), cms/antifraudбез базовой защиты нельзя выпускать ни один сайт
Аудитканонические события (*Saved/Deleted, auth)cms/audit (журнал, hash-цепочка, ретеншн, экспорт дел)журнал = свой жизненный цикл данных
Обновленияреестр модулей, версии, cms:doctor/cms:map, машина состоянийcms/updates (пайплайн cms:upgrade, Satis-клиент, UI)знание «что установлено» — ядро; процесс — модуль
ПланировщикScheduleRegistrarcms/scheduled-publishing (отложенные ревизии)регистрация cron — ось ядра; отложенный контент — не всем
Персонализацияфлаг personalized, сегментация ключа кешаcms/feature-flags, cms/ab-testingмеханизм кеша нельзя отдать модулям (5.4)
Кабинет посетителяаутентификация, роли, /auth/*cms/cabinet-b2c и далеевход нужен админке всегда; кабинет — доменная надстройка

Решённые «да, в ядре» из брейншторма остаются в силе: типы контента (Q5), ревизии (Q7), конструктор форм (Q8), виджеты как отдельная сущность (Q4) — решения. Кандидаты на новые контракты ядра копятся здесь со статусом ⬜ и вводятся только ревизией. Первый пакет (2.8, 2.9, 4.7, 6.8, 6.9, 8.8) закрыт ревизией №2 от 14.07.2026; очередь пуста.

Правила ведения реестра

  1. Новая возможность ядра → сначала строка здесь (со статусом ⬜/🧪), затем ревизия контрактов в ТЗ ядра, затем реализация. Не наоборот.
  2. Смена статуса 🧪→✅ — только со ссылкой на факт (тест, прогон, метрика пилота).
  3. Пробелы ⬜ копятся здесь и закрываются пакетно очередной ревизией контрактов (не «сразу в код»): первый пакет закрыт ревизией №2 14.07.2026, текущих ⬜ нет.
  4. Критерий, потерявший актуальность, не удаляется — зачёркивается с причиной (история решений дороже чистоты списка).

Внутренняя база знаний студии