# CALMF и блокчейн — обязательные интерфейсы ядра

Начиная с SDK 0.4.1 каждый `Engine()` содержит `engine.interfaces`.
HTML, CSS, JavaScript и WebGL-компонент находятся в wheel `yeti3-core`.
Отдельная установка темы, CDN или npm не нужны. Проверка наличия этих ресурсов
входит в автоматические самопроверки при создании ядра.

## Что видит администратор

- CALMF: вызовы, родительские связи, успех, ошибка, таймаут, повтор, отмена и прерывание.
- Блокчейн: реальные блоки и связи по хешам, номер блока, хеш события и время записи.
- Инспектор: подробности выбранного узла, масштабирование и перемещение графа.
- Списки событий и блоков работают без WebGL и доступны с клавиатуры.

Панель показывает последние 128 записей, а общий счётчик — всю текущую SDK-цепочку.
Она не объединяет автоматически отдельные исторические Django/Medical цепочки.
Реквизиты пользователей, тела запросов, токены и пароли в интерфейс не передаются.
Project Chain — журнал целостности; это не обещание распределённого консенсуса.

## Django

```python
from django.urls import path
from yeti3_core import Engine

engine = Engine()
urlpatterns = [
    path('_yeti3/core/', engine.interfaces.django_view),
    path('_yeti3/core/<str:asset>', engine.interfaces.django_view),
]
```

Должны быть включены стандартные SessionMiddleware и AuthenticationMiddleware.
Войти под активным администратором (`is_staff`) и открыть `/_yeti3/core/`.
Без прав UI и JSON возвращают 403; изменение данных через эти маршруты запрещено.
На сервере задать стабильные `YETI3_PRODUCT_ID`, `YETI3_CHAIN_PATH` и постоянный
путь CALMF. Путь цепочки и очередь должны попадать в резервное копирование.

## Другой сервер

`engine.interfaces.asset(name)` возвращает байты и Content-Type.
`engine.interfaces.snapshot()` возвращает JSON-совместимый снимок.
Адаптер обязан проверять права администратора **до** выдачи снимка и устанавливать
`Cache-Control: private, no-store`. Методы сами по себе не являются HTTP-сервером
и не проверяют произвольные токены. Для Rekvio предусмотрен адаптер существующей
серверной сессии с проверкой `role == 'admin'`.

## Развёртывание существующего сайта

В репозитории SDK: `deployment/core-runtime/site_runtime.py` и `deploy.py`.
Адаптер запускает ядро и самопроверки, оборачивает WSGI/ASGI, сохраняет CALMF до
возврата управления, а фоновый обработчик записывает блоки пакетами. Квитанция
остаётся до успешной записи; после сбоя повтор не создаёт новый блок.

`yeti3-core` 0.4.1 проверен на Python 3.11 и 3.13. Полный `yeti3-engine` и
дополнительные пакеты по-прежнему требуют Python 3.12+.
Не обновляйте старое монолитное окружение поверх файлов: используйте новый образ
или виртуальное окружение. Сохраните прежний образ и постоянные данные для отката.

## SQL-контракт для всей сети · SDK 0.4.5

Для production обязательны: автоматические проверки ядра, постоянный CALMF,
цепочка целостности значимых изменений и проверенная регрессия проекта.
`YETI3_REQUIRE_SQL_CORE=1` запрещает старт ядра без самопроверки native SQL-цепочки
и без настроенного CALMF EventStorage. Обёртка HTTP не заменяет бизнес-аудит.
Обычные GET/HEAD/OPTIONS и пассивные WebSocket-соединения остаются наблюдаемыми
CALMF, но не создают блоки; изменения домена фиксируются явно в его транзакции.

Django/PostgreSQL и Django/MySQL используют адаптер **внутри `yeti3-core`**:

```python
INSTALLED_APPS += ['yeti3_core.django_audit']
YETI3_CORE_ENGINE = 'myproject.runtime.get_engine'
YETI3_CORE_AUDIT_MODELS = ['business.Audit']
YETI3_CORE_CHAIN_MODEL = 'business.EngineBlock'
```

В фабрике ядра: `engine = attach(Engine(chain=NativeSQLChain()))`, затем регистрация
модулей и `engine.boot()`. Импорт `attach` — из `yeti3_core.django_audit.runtime`.
Ваша native цепочка остаётся единственным источником истории: адаптер не создаёт
параллельную цепочку и не переписывает старые блоки. Хранилище отклоняет SQLite.
CALMF содержит только идентификаторы, действие, время и локально вычисленные
хеши; реквизиты, значения документов, токены и тела HTTP не копируются.

Миграции создают append-only таблицу `CoreReceipt`. Сохранение обычного экземпляра
объявленной модели аудита автоматически включает обязательную запись CALMF и
цепочки в ту же SQL-транзакцию. Ошибка любой подсистемы отменяет сохранение.
`bulk_create`/`bulk_update`/`QuerySet.update`/`QuerySet.delete` объявленных
моделей блокируются менеджером ядра; прямой обход ORM не является API аудита. После миграций оператор
запускает `core_audit_guards`, устанавливая DB-защиту UPDATE/DELETE объявленных
таблиц, и `core_contract_check` перед активацией. Runtime-роль не должна владеть
схемой или иметь права удаления триггеров.

Самопроверка SQL-адаптера откатывает свои записи. Чтение WebGL/JSON использует
SQL-провайдер `engine.core_snapshot`, без открытия SQLite и без записи просмотров
в цепочку. Доступ к интерфейсу остаётся защищённым правами администратора.

### Сохранение исторической SDK-цепочки

Если проект использовал именно SDK `ProjectChain`, оператор сначала получает
согласованную копию через SQLite Backup API. Одиночная копия рабочего файла без
WAL не подходит. Рабочие файлы и резервные копии сохраняются для отката.

```sh
python manage.py core_import_chain /protected/backup/chain.sqlite3 \
  --product-id ORIGINAL_PRODUCT_ID --consistent-backup
# Только после успешного dry-run:
python manage.py core_import_chain /protected/backup/chain.sqlite3 \
  --product-id ORIGINAL_PRODUCT_ID --consistent-backup --apply
```

Импорт проверяет SQLite integrity, исходный product ID, каждую последовательность,
предыдущий и текущий хеш. SQL `SDKChainBlock` сохраняет исходные sequence,
event_digest, previous_hash, block_hash и строку captured_at без преобразования.
Повторный импорт идентичен; расхождение существующего блока отменяет транзакцию.
`SQLProjectChain(original_product_id)` продолжает эту отдельную SDK-историю.
Он не заменяет Medical/GoChain или другую native цепочку и не начисляет награды.
Команда **не переносит CALMF spool или бизнес-базы**: недоставленные квитанции
требуют отдельной сверки перед переключением рабочего процесса.
