Контракты в AngaraBase
Goal
Объяснить, что в AngaraBase понимается под словом «контракт», какие уровни контрактов существуют и какими механизмами они соблюдаются. Эта страница — для пользователей, DBA и новых контрибьюторов: чтобы при чтении документации, кода или сообщений об ошибках было понятно, на какие гарантии можно полагаться, а какие — явно вне контракта.
Что мы понимаем под контрактом
Контракт в AngaraBase — это явное обещание о наблюдаемом поведении компонента: что он принимает на вход, что возвращает, какие гарантии даёт и как ведёт себя при нарушении границ. Контракт не «лучшие намерения» и не «как обычно работает» — это формализованная договорённость, которую обязаны соблюдать обе стороны: реализация и вызывающий код (или клиент).
У контракта три ключевых свойства:
- Явность. Контракт зафиксирован в одном каноническом источнике — не в чате, не в коде комментария, не в «общем понимании команды».
- Проверяемость. Соблюдение контракта подтверждается автоматически: тестами, типами, метриками, lint-проверками.
- Fail-closed. При нарушении границы контракта система возвращает явную ошибку (с известным кодом), а не «как-нибудь продолжает работать».
Если что-то в системе не покрыто контрактом, это явно помечается как roadmap, experimental или known limitation. Поведение вне контракта может измениться без deprecation-цикла.
Уровни контрактов
В AngaraBase есть несколько уровней контрактов, каждый со своим источником истины и способом проверки.
1. SQL-контракт (внешний, для пользователя)
Что поддержано — поддержано полностью. Что не поддержано — возвращает явный SQLSTATE (0A000 feature_not_supported и др.), а не молчаливый bypass или искажённый результат.
- Источник: SQL — обзор совместимости, Известные ограничения и SQLSTATE.
- Проверка: pinned compat suite, регрессионные тесты на каждый зафиксированный SQLSTATE.
- Что это значит на практике: клиент может ловить
psycopg.errors.FeatureNotSupportedи точно знать, что попал в задокументированное ограничение, а не в баг.
2. Конфигурационный контракт
Каждый ключ конфига имеет тип, значение по умолчанию, диапазон допустимых значений и поведение при отсутствии или некорректном значении.
- Источник: Configuration, Configuration schema reference.
- Проверка: парсер отвергает неизвестные/некорректные ключи на старте (fail-closed), а не молча игнорирует.
- Изменение семантики ключа — через deprecation-цикл (см.
WRITING_RULES.md§9a).
3. Operational контракт
Метрики, USDT-зонды, имена sys.* view, формат backup/restore, формат логов и runbook-вывода — всё это
публичные имена, на которые завязан мониторинг и автоматизация оператора.
- Источник: System tables, Observability metrics checklist, Backup and restore, USDT/eBPF probes.
- Принцип: каждая ресурсная граница (RAM-бюджет буфер-пула, лимит write-set транзакции, snapshot age и т.д.) обязана иметь Prometheus-метрику и явное fail-closed поведение при нарушении. Граница без наблюдаемости — это не контракт.
4. Внутренние API-контракты (для контрибьютора)
Каждая подсистема ядра имеет публичный Rust-trait, который определяет её семантику: TableEngine,
PageProvider, TransactionLogSink, StorageIo и др. Без реализации контракта код не соберётся — это
«honest checked promise», а не «честное слово разработчика».
- Источник: doc-comments на trait-ах, Architecture overview, API Boundaries.
- Проверка: компилятор Rust + property-tests на инварианты + layering lint (
Coreне зависит отAdapters/Tooling).
5. Документационный контракт (anti-drift)
Документация — часть кода. Любое изменение публичного контракта (SQL surface, конфиг-ключи, метрики, SQLSTATE, имена сабсистем, защитные дефолты, порядок init/upgrade) обязательно сопровождается изменением AngaraBook в том же PR.
- Источник: WRITING_RULES.md §8 — Anti-drift contract.
- Проверка: pre-commit / CI прогоняют
tools/docs/lint_angarabook_public.py,tools/docs/check_public_build_security.pyи помечают расхождение как блокирующее.
Как мы соблюдаем контракты
Контракт без механизма соблюдения — декларация. В AngaraBase используется несколько слоёв принуждения, которые работают вместе.
Type system как первый рубеж
Result<T, Error>вместо panic.unwrap()/expect()в production-коде запрещены.- Bounded generics и trait-объекты вместо dynamic dispatch там, где инвариант можно зафиксировать на уровне типов.
- No-panic policy: сервер не падает из-за пользовательского ввода — он возвращает SQLSTATE.
Restrictive by default + fail-closed
Каждый компонент с ресурсной границей обязан определить:
- свою границу (например,
buffer_pool_size_mb,txn_max_write_set_mb,max_concurrent_queries), - поведение при её нарушении (явная ошибка с известным SQLSTATE),
- реакцию вызывающего кода (Reaction Propagation Contract).
Нет границы и нет fail-closed поведения — нет merge.
Pinned tests и golden datasets
Контракт SQL-совместимости и совместимости клиентов подтверждается pinned-тестами, а не «процентом совместимости». Если тест зафиксирован — изменение поведения требует либо обновления теста с обоснованием, либо отката изменения.
Подробнее: Testing and validation baseline, Golden dataset management, CI reproducibility contract.
Deprecation-цикл
Когда контракт выводится из обращения, он не исчезает молча. Применяется единый цикл: Active → Deprecated → Removed, минимум один major-релиз между объявлением Deprecated и Removed; до v1.0 — минимум две
minor-точки. Каждое изменение фазы — атомарный PR (код + AngaraBook + Migration steps).
Полный регламент: WRITING_RULES.md §9a — Deprecation policy. Public-список всех deprecated/removed контрактов: Известные ограничения и SQLSTATE.
Security gate как fail-closed для документации
Что это даёт пользователю
- Предсказуемость поведения. Если поведение задокументировано — оно стабильно в рамках мажора. Если задокументировано как ограничение со SQLSTATE — оно вернёт именно этот SQLSTATE, а не «иногда работает».
- Безопасный код клиента. Можно ловить конкретные SQLSTATE и строить логику ретраев / обработки ошибок без эвристик и парсинга текстовых сообщений.
- Понятный апгрейд. Изменение поведения публичного контракта проходит явный deprecation-цикл с migration-шагами; вы заранее видите, что и когда поменяется.
- Наблюдаемость гарантий. Каждая ресурсная граница имеет метрику; вы видите утилизацию и реджекты до того, как они станут инцидентом.
Что это даёт разработчику и контрибьютору
- Контракт компилятора, а не review-комментария. Если инвариант можно закодировать в trait или тип — он кодируется. Code review ловит то, что компилятор поймать не может.
- Один источник истины на тип знания. Не нужно «искать актуальную правду по нескольким документам»: для каждого слоя контракта есть один canonical owner.
- Предсказуемая работа с долгом. Deprecated-контракт фиксируется в
reference/known-issues.md, а если он не закрывается одним PR — в registry технического долга со статусомscheduled <target-train>. - Anti-drift в одном PR. Меняешь поведение — обновляешь AngaraBook здесь же. Не «доработать docs позже».
Что не является контрактом
Чтобы избежать ложных ожиданий, явно: контрактом не считаются:
- внутренние имена модулей, файлов и приватных функций ядра (могут меняться при рефакторинге без deprecation);
- поведение фич с frontmatter
status: experimentalили CLI-флагами--experimental-*— они никогда не считались стабильными; - тексты сообщений об ошибках (контракт —
SQLSTATEи его смысл, не текст); - не задокументированные побочные эффекты, замеченные эмпирически («у меня работает, если…»);
- бенчмарки и численные значения латентности — это observability, а не обещание производительности
(performance-claim требует pinned benchmark, см.
tools/perf_pack/).
Если вы опираетесь на что-то из этого списка в продакшене — это технический долг на стороне клиента, и очередное обновление AngaraBase его раскроет.
Links
- Project Principles §1 — Restrictive by Default — фундамент fail-closed подхода (см. также
docs/00_PROJECT_PRINCIPLES.mdв internal-сборке). - SQL — обзор совместимости — SQL-контракт.
- Известные ограничения и SQLSTATE — public-список границ и deprecated/removed контрактов.
- Configuration schema reference — конфигурационный контракт.
- Architecture overview, API Boundaries — внутренние API-контракты и layering.
- Observability metrics checklist — наблюдаемость как часть контракта.
- WRITING_RULES.md — документационный контракт (anti-drift, deprecation policy).