Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Invariant Registry — руководство инженера

Canonical registry:
Lint tool: tools/lint/invariant_refs.py
Introduced: RM-0.6.4.11

AngaraBase Invariant Registry делает ключевые архитектурные гарантии машинно-трассируемыми: каждый инвариант связывает ID → RFC/spec → тесты → метрики → evidence. Это предотвращает drift между документацией, кодом и наблюдаемостью.


Текущие инварианты (seed v0)

IDПодсистемаRiskСтатус
INV-MVCC-SNAPSHOT-VISIBILITYtx_overlaycriticalactive
INV-WAL-DURABLE-AFTER-FSYNCwalcriticalactive
INV-RECOVERY-REDO-UNDO-CLRrecoverycriticalactive
INV-RESOURCE-FAIL-CLOSEDstorage/backpressurehighactive
INV-SPILL-RECURSION-OVERFLOW-53400query/spillhighactive

Когда обязательно указывать INV-ID в коде

При изменении файлов в следующих путях необходимо включить // INV-<ID> comment или добавить файл в scoped allowlist:

ПутьОбязательный инвариант
crates/angarabase/src/tx_overlay/INV-MVCC-SNAPSHOT-VISIBILITY
crates/angarabase/src/wal/INV-WAL-DURABLE-AFTER-FSYNC
crates/angarabase/src/recovery.rsINV-RECOVERY-REDO-UNDO-CLR
crates/angarabase/src/storage/backpressure/INV-RESOURCE-FAIL-CLOSED
crates/angarabase/src/query/spill/INV-SPILL-RECURSION-OVERFLOW-53400

Пример code comment

#![allow(unused)]
fn main() {
// INV-WAL-DURABLE-AFTER-FSYNC: UndoAppend must be WAL-durable before PageDelta is written.
// See: RFC-2026-073 §4.Y — ordering invariant (UNDO-before-heap).
assert!(
    undo_lsn < page_delta_lsn,
    "WAL ordering invariant violated: undo_lsn={} >= page_delta_lsn={}",
    undo_lsn, page_delta_lsn
);
}

Как добавить новый инвариант

Шаг 1 — Добавить запись в invariants.yaml

- id: INV-<CATEGORY>-<NAME>
  title: "Human-readable name"
  surface: <module_path>           # e.g. tx_overlay, wal, query/spill
  risk_level: critical             # critical | high | medium
  owner: <team>                    # e.g. storage-team, query-team
  spec_refs:
    - rfcs/RFC-YYYY-NNN-name.md    # path relative to repo root docs/rfcs/
  test_refs:
    - crates/angarabase/src/<path>/tests.rs
  metric_refs:
    - angarabase_<metric_name>     # Prometheus metric name (not a file path)
  evidence_refs: []                # or list of pinned evidence paths
  status: active                   # or pending_evidence if refs TBD

Шаг 2 — Если refs ещё не реализованы

Используй status: pending_evidence и добавь target_rm:

  status: pending_evidence
  target_rm: RM-0.6.5.0           # train, который создаст тесты/метрики

Lint не проверяет file refs для pending_evidence инвариантов.

Шаг 3 — Проверить lint

python3 tools/lint/invariant_refs.py --check invariants.yaml
# → exit 0: OK

Шаг 4 — Добавить комментарий в код

Найди assertion/guard в исходном коде и добавь // INV-<ID> comment рядом.

Шаг 5 — Закоммитить

tools/dev/git-commit-safe.sh -m "NEW(invariants): add INV-<ID> to registry" \
  -- invariants.yaml

Поля схемы

ПолеТипОбязательноеОписание
idstringУникальный ID, начинается с INV-
titlestringКороткое человекочитаемое название
surfacestringМодуль/подсистема
risk_levelenumcritical / high / medium
ownerstringКоманда-owner
spec_refslist[path]Пути к RFC/spec (проверяются lint-ом)
test_refslist[path]Пути к тест-файлам (проверяются lint-ом)
metric_refslist[string]Prometheus-метрики (имена)
evidence_refslist[path]Pinned evidence (проверяются lint-ом; [] = нет)
statusenumactive / pending_evidence
target_rmstringдля pending_evidenceTrain, закрывающий gap

Запуск lint в CI

Lint запускается автоматически через docs/validate-docs.sh:

bash docs/validate-docs.sh
# → ✅ Invariant registry valid (5 invariant(s) checked, 0 errors)

Standalone:

python3 tools/lint/invariant_refs.py --check invariants.yaml
# exit 0 → OK
# exit 1 → broken ref или schema error (блокирует CI)

Связанные документы