docs(): added RUNBOOK, compliance matrix, ADR, refactored C4 and

repository map

zavoz
This commit is contained in:
ITQ
2026-02-24 13:17:24 +03:00
parent 7bf3ccee5c
commit 740fd2d7bd
18 changed files with 542 additions and 10 deletions
+65
View File
@@ -0,0 +1,65 @@
# Матрица соответствия: задание -> критерий -> реализация
Статусы:
- `подтверждено` - есть прямая реализация и проверка тестами/командами.
- `частично (live-demo)` - реализация есть, но критерий окончательно закрывается только на живом запуске.
| ID задания | ID критерия | Проблема/риск | Где реализовано | Как проверяется | Какие данные нужны | Статус |
|---|---|---|---|---|---|---|
| `D.4` | `B1-1` | Без предусловий жюри не сможет воспроизвести запуск | `RUNBOOK.md`, `src/backend/README.md` | Ручная проверка разделов предусловий | Python, uv, just, рабочая директория `src/backend` | подтверждено |
| `D.4` | `B1-2` | Неоднозначные команды старта ломают проверку | `RUNBOOK.md`, `src/backend/justfile` | `cd src/backend && just --list` | Доступ к `just` | подтверждено |
| `D.3` | `B1-3` | Скрытые ручные шаги делают запуск невоспроизводимым | `RUNBOOK.md`, `compose.yaml`, `compose.prod.yaml` | Полный прогон по runbook на стенде | Чистое окружение и runtime-сервисы | частично (live-demo) |
| `3.7` | `B1-4` | Сервис может стартовать, но быть неготовым к запросам | `src/backend/api/urls.py` (`/health`, `/ready`) | Runtime `curl /health` и `curl /ready` | Поднятый backend и зависимости | частично (live-demo) |
| `D.5` | `B1-5` | Без e2e happy-path нельзя доказать работоспособность | `src/backend/tests/integration/test_happy_path.py`, `src/backend/tests/integration/test_api_contract.py` | `cd src/backend && just test` | Тестовые фикстуры и встроенный test DB | подтверждено |
| `1.3, 3.4` | `B2-1` | Возврат не-default без активного эксперимента искажает контроль | `src/backend/apps/decision/services.py` | `apps.decision.tests.test_decide.DecideForFlagTest.test_no_active_experiment` | Флаг с default и без running эксперимента | подтверждено |
| `1.3, 2.7` | `B2-2` | Пользователь вне таргетинга не должен получать variant | `src/backend/apps/decision/services.py`, `src/backend/libs/dsl/*` | `apps.decision.tests.test_decide.TargetingRulesTest.test_targeting_fail_returns_default` | Эксперимент с targeting rules и mismatching subject | подтверждено |
| `1.3, 3.4` | `B2-3` | При применимом эксперименте нужен variant, а не default | `src/backend/apps/decision/services.py` | `apps.decision.tests.test_decide.DecideForFlagTest.test_running_experiment_assigns_variant` | Running experiment с вариантами | подтверждено |
| `3.5.1` | `B2-4` | Нестабильная выдача ломает статистику и UX | `src/backend/apps/decision/services.py` (`_hash_subject`) | `apps.decision.tests.test_decide.DecideForFlagTest.test_deterministic_assignment` | Повторные вызовы для одного subject | подтверждено |
| `2.2` | `B2-5` | Игнорирование weights делает тест нерепрезентативным | `src/backend/apps/decision/services.py` (`_select_variant`) | `apps.decision.tests.test_decide.SelectVariantTest.test_selects_by_weight` | Варианты с разными весами | подтверждено |
| `2.4` | `B3-1` | Без перехода в review нет управляемого процесса запуска | `src/backend/apps/experiments/services.py` (`experiment_submit_for_review`) | `apps.experiments.tests.test_services` | Draft experiment с валидными вариантами | подтверждено |
| `2.4` | `B3-2` | Без авто-перехода в approved ревью-процесс зависает | `src/backend/apps/experiments/services.py` (`experiment_approve`) | `apps.experiments.tests.test_services` | Approver + достигнутый порог approvals | подтверждено |
| `0.3, 2.4` | `B3-3` | Запуск без порога approvals делает процесс небезопасным | `src/backend/apps/experiments/services.py`, `src/backend/tests/integration/test_negative.py` | `InvalidLifecycleTransitionsTest.test_cannot_start_without_enough_approvals` | `default_min_approvals > 1`, недостаток approve | подтверждено |
| `2.5` | `B3-4` | Невалидные lifecycle переходы ломают состояние | `src/backend/apps/experiments/models.py` (`ALLOWED_TRANSITIONS`) | `src/backend/tests/integration/test_negative.py` | Эксперимент и попытка запрещённого перехода | подтверждено |
| `0.2, 0.3` | `B3-5` | Неназначенный пользователь не должен влиять на review | `src/backend/apps/reviews/selectors.py`, `src/backend/apps/experiments/services.py` | `apps.reviews.tests.test_reviews_policy`, `test_negative.ReviewPolicyEnforcementTest` | Approver group / fallback настройки | подтверждено |
| `4.5` | `B4-1` | Невалидные типы событий портят аналитику | `src/backend/apps/events/services.py` (`_validate_event_payload`) | `apps.events.tests.test_services` | Batch с ошибочными типами полей | подтверждено |
| `4.5` | `B4-2` | Отсутствие обязательных полей делает события непригодными | `src/backend/apps/events/services.py`, `src/backend/apps/events/models.py` | `apps.events.tests.test_services`, `test_negative.EventValidationIntegrationTest` | События без required base/properties | подтверждено |
| `4.3` | `B4-3` | Дубли событий завышают метрики | `src/backend/apps/events/services.py` (`_is_duplicate`) | `apps.events.tests.test_services`, `tests.integration.test_events` | Два события с одним `event_id` | подтверждено |
| `4.1, 4.4` | `B4-4` | Без связи exposure с decision теряется атрибуция | `src/backend/apps/events/models.py` (`Exposure.decision_id`) | `apps.events.tests.test_services` | Валидный `decision_id` и exposure event | подтверждено |
| `4.4.1` | `B4-5` | Конверсия без exposure не должна попадать в отчёт | `src/backend/apps/events/services.py` (`requires_exposure`, `PendingEvent`) | `apps.events.tests.test_services`, `tests.integration.test_events` | Conversion до exposure и последующая промоция | подтверждено |
| `6.2` | `B5-1` | Guardrail без metric_key нефункционален | `src/backend/apps/guardrails/models.py` (`metric`) | `apps.guardrails.tests.test_guardrails` | Guardrail с привязанной метрикой | подтверждено |
| `6.2` | `B5-2` | Guardrail без threshold не может сработать | `src/backend/apps/guardrails/models.py` (`threshold`) | `apps.guardrails.tests.test_guardrails` | Guardrail с заданным порогом | подтверждено |
| `6.3` | `B5-3` | Превышение порога должно фиксироваться автоматически | `src/backend/apps/guardrails/services.py` | `apps.guardrails.tests.test_guardrails`, `tests.integration.test_guardrails` | Метрика выше threshold в окне | подтверждено |
| `6.4` | `B5-4` | После trigger должно выполняться действие безопасности | `src/backend/apps/guardrails/services.py` (`pause`, `rollback`) | `apps.guardrails.tests.test_guardrails` | Running experiment + breach | подтверждено |
| `6.5` | `B5-5` | Без аудита триггеров нельзя объяснить остановку | `src/backend/apps/guardrails/models.py` (`GuardrailTrigger`), `apps/experiments/models.py` (`ExperimentLog`) | `apps.guardrails.tests.test_guardrails` | Triggered guardrail | подтверждено |
| `3.6` | `B5-6` | Один пользователь не должен постоянно быть в экспериментах | `src/backend/apps/decision/services.py` (`MAX_CONCURRENT_EXPERIMENTS`, `COOLDOWN_DAYS`) | `apps.decision.tests.test_decide.ParticipationLimitsTest` | Несколько running/completed экспериментов на одного subject | подтверждено |
| `5.2` | `B6-1` | Отчёт без периода неуправляем и спорный | `src/backend/apps/reports/services.py` | `apps.reports.tests.test_reports.CalculateMetricValueTest.test_period_filter` | События внутри/вне окна периода | подтверждено |
| `5.3` | `B6-2` | Без разреза по вариантам нельзя сравнивать A/B | `src/backend/apps/reports/services.py` (`variant_reports`) | `apps.reports.tests.test_reports.BuildExperimentReportTest` | Эксперимент минимум с двумя вариантами | подтверждено |
| `5.4` | `B6-3` | Отчёт должен показывать именно выбранные метрики эксперимента | `src/backend/apps/metrics/models.py`, `src/backend/apps/reports/services.py` | `apps.reports.tests.test_reports` | `ExperimentMetric` привязки | подтверждено |
| `2.6` | `B6-4` | Нужна фиксация исхода (`rollout/rollback/no_effect`) | `src/backend/apps/experiments/services.py` (`experiment_complete`) | `apps.experiments.tests.test_services` | Completed experiment и выбранный outcome | подтверждено |
| `2.6` | `B6-5` | Решение без rationale теряет объяснимость | `src/backend/apps/experiments/services.py` (валидация `rationale`) | `tests.integration.test_negative.InvalidLifecycleTransitionsTest.test_cannot_complete_without_rationale` | Пустой rationale при complete | подтверждено |
| `D.5(B7)` | `B7-1` | Неясный нейминг усложняет поддержку и демо | `src/backend/apps/*`, `src/backend/api/v1/*` | Архитектурный walkthrough | Репозиторий проекта | подтверждено |
| `D.5(B7)` | `B7-2` | Без границ модулей растёт связность и регрессии | `src/backend/apps/*`, `src/backend/api/v1/*` | Проверка структуры директорий и зависимостей | Репозиторий проекта | подтверждено |
| `D.4, D.6` | `B7-3` | Без матрицы тяжело трассировать критерии | `compliance-matrix.md` | Проверка заполнения всех ID | Этот файл | подтверждено |
| `D.4` | `B7-4` | Без ADR сложно доказать осознанные trade-off | `ADR/04-decisions.md` | Сверка решений с кодом | ADR и код `src/backend` | подтверждено |
| `D.4` | `B7-5` | Нужна контекстная диаграмма границ системы | `assets/plantuml/raw/c4-context.puml` | Просмотр диаграммы | PlantUML файл | подтверждено |
| `D.4` | `B7-6` | Нужна container-диаграмма взаимодействий | `assets/plantuml/raw/c4-container.puml` | Просмотр диаграммы | PlantUML файл | подтверждено |
| `D.4` | `B7-7` | Нужна component-диаграмма по критичному пути | `assets/plantuml/raw/c4-component-critical-path.puml` | Просмотр диаграммы | PlantUML файл | подтверждено |
| `D.4` | `B7-8` | Без карты репозитория навигация медленная | `MAP.md` | Проверка ссылок на точки входа | Файл `MAP.md` | подтверждено |
| `D.7` | `B7-9` | Неявные упрощения искажают ожидания жюри | `ADR/07-simplifications.md` | Проверка явного списка ограничений | ADR пакет | подтверждено |
| `D.5(B8)` | `B8-1` | Без негативных тестов edge-cases не покрыты | `src/backend/tests/integration/test_negative.py` | `cd src/backend && just test` | Тестовая БД и фикстуры | подтверждено |
| `D.5(B8)` | `B8-2` | Критичный поток нужен в интеграционных/контрактных тестах | `src/backend/tests/integration/test_happy_path.py`, `src/backend/tests/integration/test_api_contract.py` | `cd src/backend && just test` | Тестовые фикстуры | подтверждено |
| `D.4` | `B8-4` | Нужен измеримый отчёт по покрытию | `src/backend/justfile`, `src/backend/pyproject.toml` | `cd src/backend && just test-coverage && just show-coverage` | Coverage tool из dev dependencies | подтверждено |
| `3.7` | `B9-1` | Readiness должен быть однозначным и проверяемым | `src/backend/api/urls.py` (`/ready`) | Runtime: `curl -i /ready` после старта | Поднятые cache/db/storage/celery | частично (live-demo) |
| `3.7` | `B9-2` | Нужен отдельный liveness probe | `src/backend/api/urls.py` (`/health`) | Runtime: `curl -i /health` | Поднятый backend | подтверждено |
| `D.5(B9)` | `B9-3` | Без метрик нет наблюдаемости hot-path | `src/backend/config/settings/base.py`, `src/backend/apps/decision/services.py`, `src/backend/api/v1/events/endpoints.py` | Runtime: `curl /metrics` | Поднятый backend | подтверждено |
| `D.5(B9)` | `B9-4` | Неструктурированные логи сложны для алертов и анализа | `src/backend/config/settings/base.py` (json formatter, django-guid) | Запуск в non-debug и просмотр stdout | Конфигурация `DJANGO_DEBUG=false` | подтверждено |
| `D.5(B9)` | `B9-6` | Рост трафика/данных может деградировать latency даже после оптимизаций | `src/backend/apps/decision/services.py`, `src/backend/apps/reports/services.py`, `src/backend/apps/events/tasks.py`, `ADR/04-decisions.md` (P1-P4) | Код-ревью + live-demo под нагрузкой | Сценарий увеличенного трафика и наблюдение очереди/latency | частично (live-demo) |
| `D.5(B9)` | `B9-7` | Без индексов и оптимизаций горячие запросы дорожают | `src/backend/apps/experiments/models.py`, `src/backend/apps/events/models.py`, `src/backend/apps/guardrails/models.py`, `src/backend/apps/notifications/models.py`, `src/backend/apps/learnings/models.py` | Схема моделей и миграций | БД-схема проекта | подтверждено |
| `D.5(B10)` | `B10-1` | Отсутствие автоматического линтинга снижает качество | `src/backend/justfile`, `src/backend/pyproject.toml`, `.gitlab-ci.yml` | `cd src/backend && just lint` | Dev dependencies | подтверждено |
| `D.5(B10)` | `B10-2` | Отсутствие форматирования повышает шум в diff | `src/backend/justfile`, `src/backend/pyproject.toml`, `.gitlab-ci.yml` | `cd src/backend && just format` | Dev dependencies | подтверждено |
| `7` | `FX-1` | Без рабочего сценария уведомления бесполезны | `src/backend/apps/notifications/*`, `src/backend/api/v1/notifications/*` | `cd src/backend && uv run python manage.py test apps.notifications.tests.test_notifications api.v1.notifications.tests.test_notifications_api` | Notification channels/rules/log fixtures | подтверждено |
| `7` | `FX-2` | Нужны явные ограничения по каналам и шумоподавлению | `ADR/07-simplifications.md`, `ADR/04-decisions.md`, `src/backend/apps/notifications/services.py` | Сверка docs и реализации rate-limit/dedup | Документация + код notifications | подтверждено |
| `9` | `FX-1` | Без рабочего knowledge base повторяются эксперименты | `src/backend/apps/learnings/*`, `src/backend/api/v1/learnings/*` | `cd src/backend && uv run python manage.py test apps.learnings.tests.test_learnings api.v1.learnings.tests.test_learnings_api` | Learning fixtures, experiments, tags | подтверждено |
| `9` | `FX-2` | Нужны явные ограничения алгоритма похожести | `ADR/07-simplifications.md`, `ADR/04-decisions.md`, `src/backend/apps/learnings/services.py` | Сверка docs и реализации similarity scoring | Документация + код learnings | подтверждено |
| `11` | `FX-1` | Без резолва конфликтов метрики неинтерпретируемы | `src/backend/apps/conflicts/*`, `src/backend/api/v1/conflicts/*`, `src/backend/apps/decision/services.py` | `cd src/backend && uv run python manage.py test apps.conflicts.tests.test_conflicts api.v1.conflicts.tests.test_conflicts_api` | Эксперименты в доменах с policy `mutual_exclusion/priority` | подтверждено |
| `11` | `FX-2` | Нужны явные границы конфликтных политик | `ADR/07-simplifications.md`, `ADR/04-decisions.md`, `src/backend/apps/conflicts/services.py` | Сверка docs и `resolve_domain_conflict` | Документация + код conflicts | подтверждено |