Agent: - lifecycle: run tracking, middleware hardening, langgraph setup - tests: agent lifecycle + langgraph setup coverage Backend: - async_job_runner: resilience hardening, tests - agent_conversations: run lifecycle integration - translate: scheduler + orchestrator SQL adjustments - schemas/services: agent_lifecycle model extensions Frontend: - TaskDrawer: UX improvements - TaskLogPanel/Viewer: safety hardening, i18n (en/ru) - FilterBar: report filters contract + tests - Reports page: layout adjustments Specs: - 036-agent-test-stabilization: runs contract, modules, events - 037-superset-baseline-engine: catalog schema, testing API, modules - 038-dashboard-scenario-model: scenario schema, capture profile, modules - 039-dashboard-scenario-ui: screen models, release verification UX, modules - dashboard-verification-usecases: new cross-cutting spec
61 KiB
Подсистема верификации дашбордов (036–039)
Для Project owner, BI-аналитиков и разработчиков FI-ПО. Июль 2026. Статус: спецификация готова, начало реализации.
О чём эта подсистема
Сегодня проверка дашборда после изменений выглядит так: открыть в браузере, прокликать фильтры, сверить числа глазами с Excel, сделать скриншот «на память». Через месяц повторить невозможно — никто не помнит, какие фильтры были применены и какие значения считались правильными.
Подсистема верификации дашбордов делает три вещи:
- Фиксирует эталон — какие значения метрик считаются правильными для данного дашборда с данными фильтрами на момент релиза.
- Автоматически проверяет — совпадают ли текущие значения с эталоном при каждом деплое на PREPROD и PROD, еженедельно по расписанию и после каждой ETL-загрузки.
- Показывает изменения — что именно поменялось в структуре дашборда между релизами (фильтры, колонки, чарты), даже если числа не изменились.
Всё это встроено в существующий релизный пайплайн (dev → preprod → prod через git) и не требует отдельного запуска.
Почему это важно для каждой роли
Project owner
Вы отвечаете за корректность данных в хранилище. Сегодня вы узнаёте, что ETL перезалил данные за закрытый период, только когда аналитик случайно замечает расхождение в отчёте — через две недели после факта.
С этой подсистемой:
- Каждый понедельник в 9:00 система автоматически проверяет все ключевые дашборды. Если данные за закрытый период изменились задним числом — вы получаете алерт в Rusal Pulse и автоматически созданный инцидент в YouTrack в течение минуты после обнаружения.
- Публикация новых релизов дашборда блокируется до расследования — нельзя выкатить новую версию, пока не разобрались с целостностью данных.
- Для каждого эталонного значения хранится
source_response_hash— хеш ответа Superset API на момент фиксации. Это объективный proof того, что данные были именно такими.
BI-аналитику
Вы проверяете дашборды перед релизом. Сегодня вы вручную сверяете метрики, делаете скриншоты, сравниваете XLSX-выгрузки с экраном. Это занимает 30–40 минут на дашборд и на 100% зависит от вашей внимательности.
С этой подсистемой:
- Вы нажимаете одну кнопку на странице дашборда в superset-tools — «Создать сценарий тестирования». Система сама предлагает план проверки: какие метрики сверить, какие скриншоты снять, какие фильтры применить.
- Вы заполняете бизнес-параметры (дата, контрагент) — не технические. Система сама знает, какие инструменты использовать.
- Результат: человекочитаемый отчёт — не JSON, а страница с таблицей «что проверено, какие значения, совпадает ли с эталоном».
- При создании нового релиза система автоматически сравнивает метрики с предыдущим релизом и показывает, что изменилось. Вы только подтверждаете.
- Визуальную проверку (скриншоты) анализирует LLM — подсвечивает подозрительные места, вы принимаете решение.
Разработчику FI-ПО
Вы отвечаете за релизный пайплайн дашбордов. Сегодня деплой на PREPROD и PROD — это чисто техническая операция: упаковали, залили, проверили, что Superset не упал. Содержательная проверка («а правильно ли дашборд показывает данные?») остаётся на совести аналитика и часто пропускается.
С этой подсистемой:
- Верификация встроена в существующий пайплайн как дополнительные gates. Не нужно менять процесс — нужно только добавить policy.
- При деплое на PREPROD: автоматический StructureDiff — если фильтр потерял scope или чарт удалён, деплой блокируется до подтверждения.
- При создании релиза: автоматическая метрическая проверка. Если значения разъехались — релиз не создаётся.
- При публикации в PROD: автоматическая проверка immutability закрытых периодов. Если данные изменились задним числом — публикация блокируется.
- Всё настраивается через
VerificationPolicyвGitRepository.release_policy— per-dashboard, с наследованием от installation-wide defaults. - Baseline.yaml живёт в том же git-репозитории, что и дашборд. Версионируется вместе с ним. Никакой отдельной базы, никакой синхронизации.
Сценарии использования
UC-1: Ad-hoc проверка дашборда аналитиком
Кто: BI-аналитик.
Когда: перед релизом, при подозрении на проблему, при аудите.
Режим: диалог с агентом.
1. Аналитик открывает дашборд FI-0080 в superset-tools (страница дашборда в нашем приложении, не в самом Superset), среда ss-dev.
2. Нажимает «Создать сценарий тестирования».
3. Попадает в /agent (встроенный чат superset-tools). Система уже знает контекст:
dashboard_id=42, среда=ss-dev, цель=build_dashboard_test_scenario.
4. Агент: «Дашборд FI-0080. Что проверяем?»
Аналитик: «Фильтры, метрику просроченной ДЗ, XLSX-выгрузку».
5. Агент показывает сценарий из 18 шагов — как бизнес-план, не как код:
┌──────────────────────────────────────────────────────────────┐
│ Сценарий проверки FI-0080 │
│ │
│ [Открыть дашборд] → [Применить фильтры] → [Метрика через API]│
│ → [Скачать XLSX] → [Сравнить с baseline] → [Отчёт] │
│ │
│ Шагов: 18 | Инструменты: browser, Superset API, XLSX, report │
└──────────────────────────────────────────────────────────────┘
6. Аналитик: «Добавь скриншоты вкладки с графиком».
Агент обновляет сценарий — теперь 20 шагов.
7. Аналитик заполняет параметры:
┌──────────────────────────────────────────────────────────────┐
│ Дата тестирования [29.05.2026] │
│ Контрагент [АСК] │
│ Baseline [использовать утверждённый (v1.2.3)] │
│ Скриншоты [✓] │
└──────────────────────────────────────────────────────────────┘
8. Агент генерирует черновик. Аналитик видит артефакты:
┌──────────────────────────────────────────────────────────────┐
│ dashboard_42_test_scenario/ │
│ ├── scenario.yaml ✓ │
│ ├── runner.plan.json ✓ │
│ ├── xlsx_assertions.py ⚠ нужен просмотр │
│ ├── report_template.md ✓ │
│ └── evidence/ │
│ └── screenshot_debt_tab.webp ✓ │
└──────────────────────────────────────────────────────────────┘
9. Аналитик жмёт «Сохранить». Появляется подтверждение:
┌──────────────────────────────────────────────────────────────┐
│ Сохранить артефакты? │
│ Путь: tests/generated/dashboards/fi_0080/ │
│ Файлов: 5 | Предупреждений: 1 │
│ │
│ [Подтвердить] [Отмена] │
└──────────────────────────────────────────────────────────────┘
10. Готово. Артефакты в git-репозитории дашборда.
Результат: проверка выполнена, результаты сохранены, эталоны зафиксированы. В любой момент можно повторить.
UC-2: Релиз дашборда с автоматической верификацией
Кто: Разработчик дашборда + Release manager.
Когда: каждый цикл dev → preprod → prod.
Режим: автоматический + structured panels (без агента).
РАЗРАБОТЧИК вносит изменения в Superset DEV:
• Добавлен chart_400 «Распределение по регионам»
• Исправлен layout главной вкладки
• chart_300 «Детализация по месяцам» — удалён (устарел)
SYNC → COMMIT → PUSH → жмёт «Deploy to PREPROD».
───────────────────────────────────────────────────────────
АВТОМАТИЧЕСКИ (deploy hook):
───────────────────────────────────────────────────────────
StructureDiff: текущий dev vs baseline из v1.2.3 (последний релиз)
Результат:
┌──────────────────────────────────────────────────────────┐
│ ⛔ CRITICAL (1) │
│ chart_300 удалён │
│ Был в v1.2.3, отсутствует в текущем dev. │
│ │
│ ⚠ WARNING (1) │
│ chart_128: порядок колонок изменён │
│ Было: [Контрагент, Сумма, %] → Стало: [Контрагент, %, Сумма]│
│ Затронуто: XLSX-выгрузка, скриншоты │
│ │
│ ℹ INFO (1) │
│ chart_400: новый чарт │
└──────────────────────────────────────────────────────────┘
→ DEPLOY ЗАБЛОКИРОВАН (CRITICAL не решён).
Разработчик на странице PREPROD-деплоя:
Видит красную карточку «chart_300 удалён».
Жмёт «Подтвердить», вводит комментарий:
«Chart устарел, заменён на chart_400 «Распределение по регионам»»
→ CRITICAL разрешён.
Жмёт «Deploy to PREPROD» повторно → деплой выполнен.
───────────────────────────────────────────────────────────
АВТОМАТИЧЕСКИ (post-deploy hook):
───────────────────────────────────────────────────────────
VerificationRun(trigger=deploy_to_preprod):
Метрическая проверка:
Просроченная ДЗ 1 234 567 ✓
Доля просрочки 12,4% ✓
Всего должников 342 ✓
chart_400 (новый) — ⚠ нет baseline
...
Итого: 6✓ 1⚠ 0✕
Визуальная проверка:
2 скриншота снято, LLM находок нет → ✓
XLSX:
checksum изменился (порядок колонок другой) → ⚠
Overall: ⚠ WARN
Страница PREPROD-деплоя, вкладка «Верификация»:
┌──────────────────────────────────────────────────────────┐
│ Верификация PREPROD │
│ │
│ Структура: ✓ (CRITICAL решён) │
│ Метрики: 6✓ 1⚠ — chart_400 без baseline │
│ Визуально: ✓ │
│ XLSX: ⚠ порядок колонок изменён │
│ │
│ [Перезапустить] [Подтвердить] │
└──────────────────────────────────────────────────────────┘
Разработчик жмёт «Validate deployment» — валидация пройдена.
───────────────────────────────────────────────────────────
RELEASE MANAGER создаёт релиз:
───────────────────────────────────────────────────────────
Имя: «v1.3.0 — график по регионам, фикс layout»
Версия: v1.3.0
→ Жмёт «Create release».
АВТОМАТИЧЕСКИ:
• VerificationRun для PREPROD = WARN → OK (политика разрешает)
• Baseline-наследование от v1.2.3:
- 4 метрики унаследованы (chart_hash не изменился)
- 2 метрики переизвлечены (chart_hash изменился)
- 1 метрика — новая (chart_400)
• StructureDiff v1.2.3 → v1.3.0: 0 CRITICAL, 1 WARNING, 1 INFO
• VerificationRun(trigger=release_create): ✓ PASS
Страница релиза v1.3.0:
┌──────────────────────────────────────────────────────────┐
│ Релиз v1.3.0 │
│ │
│ Верификация: ✓ PASS │
│ Структура: 0/1/1 (все решены) │
│ Baseline: 7 метрик (4 унаследовано, 2 переизвлечено, │
│ 1 новый) │
│ │
│ [Approve] │
└──────────────────────────────────────────────────────────┘
Release manager жмёт «Approve», вводит комментарий.
Затем жмёт «Publish to PROD».
АВТОМАТИЧЕСКИ (publish hook):
• PREPROD matches release ✓
• drift_status = in_sync ✓
• VerificationRun re-check ✓
• Immutability: закрытых периодов нет → OK
Релиз v1.3.0 опубликован в PROD.
Post-publish: VerificationRun фиксирует метрики PROD
для будущих scheduled-проверок.
Результат: релиз прошёл через структурную, метрическую и визуальную проверку автоматически. Аналитик и release manager только подтверждали решения на каждом gate.
UC-3: Еженедельная автоматическая проверка PROD
Кто: никто (полный автомат).
Когда: каждый понедельник 9:00 MSK.
Режим: cron → алерт при проблемах.
Scheduler: понедельник 9:00.
Для каждого дашборда с policy.scheduled_verification_enabled=true:
1. Берёт последний опубликованный релиз
2. Берёт его baseline.yaml из git
3. Для каждой метрики: Superset API запрос → сравнение с expected
4. Для закрытых периодов: сравнение source_response_hash
5. Результат: VerificationRun(trigger=scheduled, env=prod)
ТРИ ВОЗМОЖНЫХ ИСХОДА:
Сценарий A — Всё OK:
Все метрики совпадают. Закрытые периоды не нарушены.
→ VerificationRun: ✓ PASS
→ Тихая запись в историю проверок
→ На странице дашборда зелёный значок «Последняя проверка: ✓»
Сценарий B — Данные изменились (открытый период):
Метрика «Всего должников»: было 342 → стало 358
→ VerificationRun: ⚠ WARN
→ Алерт в Rusal Pulse #dashboard-alerts (низкий приоритет):
«FI-0080: 1 метрика изменилась. Всего должников: 342→358 (+16)»
→ На странице дашборда жёлтый значок
Сценарий C — Immutability violation (закрытый период):
Метрика «Просроченная ДЗ», период май 2026 (закрыт 01.06)
source_response_hash изменился!
→ VerificationRun: ⛔ BLOCKED (immutability_violation)
→ CRITICAL алерт в Rusal Pulse #incidents:
«⛔ FI-0080: НАРУШЕНИЕ НЕИЗМЕННОСТИ ДАННЫХ.
Период: май 2026. Метрика: Просроченная ДЗ.
Baseline (01.06): 1 234 567.89
Сейчас (14.07): 1 500 000.00
[Подробнее] [Создать инцидент]»
→ Автоматически создан YouTrack issue
→ Публикация новых релизов FI-0080 заблокирована
→ На странице дашборда красный баннер до расследования
Результат: целостность данных проверяется автоматически и непрерывно. Нарушения детектятся в день возникновения, а не через две недели руками аналитика.
UC-4: ETL-triggered — проверка после загрузки данных
Кто: никто (event-driven).
Когда: сразу после завершения ETL-процесса.
Режим: maintenance event → верификация затронутых дашбордов.
ETL-процесс «Загрузка финансовых данных» завершился в 06:15.
Maintenance event: ended, datasets_affected=[
dataset_finance_debt (id=77),
dataset_finance_receivables (id=82)
]
Event listener (автоматически):
1. Ищет все дашборды, использующие затронутые dataset-ы:
→ FI-0080 (dataset 77), FI-0042 (dataset 82)
2. Для каждого запускает VerificationRun(trigger=etl_completed):
— Метрическая проверка ТОЛЬКО метрик на затронутых dataset-ах
— Immutability check для закрытых периодов
3. Результаты через 45 секунд:
FI-0080: ✓ PASS — данные загружены корректно
FI-0042: ⚠ WARN — 2 метрики изменились (периоды открытые)
4. Сводный алерт:
«ETL «Загрузка финансовых данных» завершён в 06:15.
Проверено дашбордов: 2. Результат: 1✓ 1⚠.
FI-0042: Всего контрагентов 847→852, Средний срок 34→36 дней.
[Подробнее]»
Результат: Project owner узнаёт о проблеме с данными через минуту после завершения ETL, а не когда аналитик заметит расхождение в отчёте через три дня.
UC-5: Immutability violation — полный сценарий
Кто: Автоматика → Project owner → DBA.
Когда: scheduled-проверка обнаружила изменение данных задним числом.
Режим: автоматическое обнаружение + ручное расследование.
Понедельник 14.07.2026, 9:00. Scheduled-проверка FI-0080.
Для baseline_entry «Просроченная ДЗ» (период май 2026, закрыт 01.06):
immutability.enabled = true
immutability.policy = block_publish
expected.value (на 01.06) = 1 234 567.89
source_response_hash (на 01.06) = sha256:aaa111...
Сейчас (14.07, тот же запрос к Superset):
actual.value = 1 500 000.00
source_response_hash = sha256:bbb222... ← НЕ СОВПАДАЕТ!
→ IMMUTABILITY VIOLATION
АВТОМАТИЧЕСКИ:
1. VerificationRun.status = BLOCKED
2. Блокировка publish для всех pending-релизов FI-0080
3. Алерт в Rusal Pulse #incidents + email Project owner
4. YouTrack issue создан автоматически:
«Immutability violation: FI-0080 / Просроченная ДЗ / май 2026»
5. На странице дашборда — красный баннер:
┌──────────────────────────────────────────────────────────┐
│ ⛔ НАРУШЕНИЕ НЕИЗМЕННОСТИ ДАННЫХ │
│ │
│ Дашборд: FI-0080 │
│ Период: май 2026 (закрыт 01.06.2026) │
│ Метрика: Просроченная ДЗ │
│ │
│ Значение при закрытии периода: 1 234 567.89 │
│ Значение сейчас: 1 500 000.00 │
│ Расхождение: +265 432.11 (+21,5%) │
│ │
│ Возможная причина: данные за май были изменены задним │
│ числом (перезаливка ETL, исправление ошибки в источнике). │
│ │
│ [Создать инцидент] [Скачать evidence] [Уведомить DBA] │
└──────────────────────────────────────────────────────────┘
Project owner (через 2 минуты после алерта):
Открывает страницу VerificationRun.
Видит: source_response_hash изменился, все предыдущие проверки (8 недель) были OK.
Жмёт «Уведомить DBA».
DBA расследует:
Выясняет: в пятницу 11.07 ETL-процесс перезалил данные за май
из-за ошибки в конфигурации источника (подключился к тестовой базе).
Данные восстановлены из бэкапа.
DBA закрывает инцидент в YouTrack.
Project owner перезапускает scheduled-проверку вручную:
→ source_response_hash снова sha256:aaa111 → immutability violation cleared
→ VerificationRun: ✓ PASS
→ Блокировка публикации новых релизов FI-0080 снята
→ Красный баннер на странице дашборда исчезает
Хронология:
9:00 — scheduled-проверка запущена
9:01 — violation обнаружен, алерт отправлен
9:03 — архитектор уведомлён
9:15 — DBA начал расследование
10:30 — причина найдена, данные восстановлены
10:35 — перепроверка: ✓ PASS, блокировка снята
Время от обнаружения до разрешения: 1 час 35 минут.
Без подсистемы: аналитик заметил бы расхождение через 1–2 недели.
Результат: нарушение целостности данных детектится, расследуется и исправляется за часы, а не за недели. Блокировка публикации новых релизов предотвращает каскадное распространение проблемы.
UC-6: Структурная регрессия фильтра
Кто: Разработчик дашборда.
Когда: при деплое на PREPROD.
Режим: pipeline gate — блокировка до подтверждения.
Разработчик меняет дашборд в DEV:
Фильтр «Контрагент»: раньше применялся к chart_128 и chart_200,
теперь — только к chart_128 (поменял scope).
Разработчик НЕ заметил, что chart_200 потерял фильтрацию.
Числовые метрики chart_128 не изменились — числовая проверка PASS.
SYNC → COMMIT → Deploy to PREPROD.
АВТОМАТИЧЕСКИ:
StructureDiff: текущий dev vs baseline из последнего релиза
Change detected:
target: native_filters[contractor].scope
kind: filter_scope_narrowed
severity: CRITICAL
before: [chart_128, chart_200]
after: [chart_128]
affected_charts: [200 — «Динамика по контрагентам»]
rationale: «Фильтр «Контрагент» больше не фильтрует chart_200.
Данные chart_200 будут показываться без ограничения
по контрагенту, хотя раньше фильтровались.»
→ DEPLOY ЗАБЛОКИРОВАН.
Разработчик на странице PREPROD-деплоя видит:
┌──────────────────────────────────────────────────────────┐
│ ⛔ CRITICAL: фильтр «Контрагент» потерял scope │
│ │
│ Chart_200 «Динамика по контрагентам» больше │
│ не фильтруется. Его данные теперь показывают │
│ ВСЕХ контрагентов, а не выбранного. │
│ │
│ Это ожидаемо? │
│ │
│ [Да, подтвердить] [Нет, буду править] │
└──────────────────────────────────────────────────────────┘
Вариант A (ошибка):
Разработчик: «Нет, буду править»
→ возвращается в DEV, правит scope фильтра
→ SYNC → COMMIT → Deploy (StructureDiff снова, теперь OK)
Вариант B (осознанное изменение):
Разработчик: «Да, подтвердить»
Причина: «Chart_200 теперь использует dataset-level фильтр
в виртуальном датасете. Dashboard-фильтр не нужен.»
→ CRITICAL resolved
→ Деплой разблокирован
НО: метрическая проверка для chart_200 показывает WARNING —
baseline был с фильтром, новые данные без фильтра.
Разработчик подтверждает: метрики переизвлечены.
Результат: структурная регрессия поймана до того, как сломанный дашборд попал в PREPROD. Раньше это заметил бы только аналитик при ручной проверке — или никто.
UC-7: Baseline-наследование при создании релиза
Кто: Release manager.
Когда: создание нового релиза.
Режим: structured panel — таблица + кнопка «Подтвердить».
Релиз v1.4.0 создаётся на основе PREPROD.
Предыдущий релиз: v1.3.0, baseline.yaml с 7 метриками.
АВТОМАТИЧЕСКИ:
Система сравнивает content_hash каждого чарта между v1.3.0 и v1.4.0.
┌──────────────────────────────────────────────────────────┐
│ Baseline-наследование: v1.3.0 → v1.4.0 │
│ │
│ Метрика v1.3.0 v1.4.0 Статус │
│ ──────────────────────────────────────────────────────── │
│ Просроченная ДЗ 1 234 567 1 234 567 ↻ унасл │
│ Доля просрочки 12,4% 12,4% ↻ унасл │
│ Всего должников 342 342 ↻ унасл │
│ XLSX checksum sha256:hhh sha256:hhh ↻ унасл │
│ ──────────────────────────────────────────────────────── │
│ Топ контрагентов 1 500 000 1 520 000 ⚡ переизв│
│ chart_hash изменился. Значение переизвлечено из PREPROD.│
│ Δ: +20 000 (+1,3%) │
│ ──────────────────────────────────────────────────────── │
│ Динамика ДЗ 342 355 ⚡ переизв│
│ chart_hash изменился. Значение переизвлечено из PREPROD.│
│ Δ: +13 │
│ ──────────────────────────────────────────────────────── │
│ Распределение — 845 000 ✚ новый │
│ Новый чарт (chart_500), значения извлечены из PREPROD. │
└──────────────────────────────────────────────────────────┘
Итого: 4 унаследовано, 2 переизвлечено, 1 новый.
Release manager проверяет переизвлечённые значения:
• «Топ контрагентов» +1,3% — ожидаемо, новый контрагент в мае.
• «Динамика ДЗ» +13 — ожидаемо, сезонный рост просрочки.
Жмёт «Подтвердить все» — baseline.yaml для v1.4.0 зафиксирован.
Релиз создан.
Результат: baseline не требует ручного перезаполнения при каждом релизе. Release manager только проверяет автоматически вычисленный diff и подтверждает. Наследование гарантирует, что эталоны не теряются между релизами.
Архитектурная карта
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ 039 UI Layer │
│ ┌─────────────────────┐ ┌──────────────────────────────────┐ │
│ │ Agent Workspace │ │ Pipeline Verification Views │ │
│ │ (диалог с агентом) │ │ (автоматические страницы) │ │
│ │ │ │ │ │
│ │ • ScenarioPreview │ │ • VerificationStatusBadge │ │
│ │ • ParameterPanel │ │ • StructureDiffPanel │ │
│ │ • ArtifactPreview │ │ • VerificationHistoryList │ │
│ │ • EvidencePanel │ │ • ImmutabilityViolationBanner │ │
│ │ • ConfirmationCard │ │ │ │
│ └────────┬────────────┘ └──────────────┬───────────────────┘ │
│ │ │ │
│ 038 Scenario Model │ │
│ ┌─────────────────────┐ │ │
│ │ • ScenarioCompiler │ │ │
│ │ • Validator │ │ │
│ │ • PackCompiler │ │ │
│ │ • CaptureDispatch │ │ │
│ │ • VlmAnalysis │ │ │
│ └────────┬────────────┘ │ │
│ │ │ │
│ 037 Baseline Engine │ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ • QueryModel.Inspect • Comparison.Compare │ │
│ │ • Filters.Normalize • Structure.Diff │ │
│ │ • QueryExecutor • Immutability.Detect │ │
│ │ • Result.Normalize • Release.ExtractBaseline │ │
│ │ • Catalog.Load • Visual.Compare │ │
│ └────────────────────────┬─────────────────────────────┘ │
│ │ │
│ 036 Agent Run Stabilization │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ • AgentRun (manual/scheduled/etl_completed/...) │ │
│ │ • DraftArtifact (screenshot_evidence, ...) │ │
│ │ • ApprovalGate (HITL) │ │
│ │ • Evidence.Adapter (ScreenshotService bridge) │ │
│ │ • VerificationRun (AgentRun ↔ DashboardRelease) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Git Repository (существующий) Superset API │
│ ┌────────────────────────────┐ ┌────────────────────────────┐ │
│ │ • baseline.yaml │ │ • chart data │ │
│ │ • visual_baselines/ │ │ • dataset query │ │
│ │ • verification_report.md │ │ • dashboard export │ │
│ │ • DashboardRelease │ │ • native filters │ │
│ └────────────────────────────┘ └────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Граница: где нужен агент, а где нет
| Use Case | Агент? | Интерфейс |
|---|---|---|
| UC-1 Ad-hoc проверка | ✅ Да | Диалог + structured panels |
| UC-2 Релиз с верификацией | ❌ Нет | Страницы деплоя/релиза, кнопки Confirm/Dismiss |
| UC-3 Scheduled проверка | ❌ Нет | Полный автомат, алерт при проблемах |
| UC-4 ETL-triggered | ❌ Нет | Полный автомат, event-driven |
| UC-5 Immutability violation | ❌ Нет | Алерт → страница VerificationRun → расследование |
| UC-6 Структурная регрессия | ❌ Нет | Страница PREPROD-деплоя, кнопка Confirm/Dismiss |
| UC-7 Baseline-наследование | ❌ Нет | Страница создания релиза, таблица + «Подтвердить» |
Агент нужен только в одном сценарии из семи — когда аналитик создаёт сценарий проверки с нуля или итеративно его уточняет. Все остальные сценарии — это structured views с кнопками, которые потребляют данные из автоматически созданных VerificationRun-ов.
Оценка трудозатрат
Сводка
┌──────────────────────┬──────────┬──────────┬──────────┬─────────────────┐
│ Показатель │ Backend │ Frontend │ DevOps │ Итого │
├──────────────────────┼──────────┼──────────┼──────────┼─────────────────┤
│ FTE (ставок) │ 1.5 │ 1.0 │ 0.3 │ 2.8 FTE │
│ Календарных месяцев │ 5 │ 5 │ 2 │ 5 месяцев │
│ FTE-месяцев │ 7.0 │ 4.5 │ 0.5 │ 12.0 FTE-мес │
│ Человекочасов (net) │ 1 120 │ 720 │ 80 │ 1 920 ч │
│ Человекочасов (full) │ 1 400 │ 900 │ 100 │ 2 400 ч │
└──────────────────────┴──────────┴──────────┴──────────┴─────────────────┘
Full = net + 25% (code review, совещания, документация, непродуктивное время).
1 человекочас net = 1 час написания кода / тестов / отладки.
Детализация по фичам
┌──────┬──────────────────────────┬──────────┬────────────┬─────────┬──────────┐
│ Фича │ Компоненты │ LoC │ Календарь │ FTE │ Человеко-│
│ │ │ │ (недель) │ (ставок)│ часы net │
├──────┼──────────────────────────┼──────────┼────────────┼─────────┼──────────┤
│ │ │ │ │ │ │
│ 036 │ AgentRun, AgentRunEvent, │ ~8 000 │ 5 │ 1.0 BE │ 200 BE │
│ │ DraftArtifact, │ backend │ │ 0.3 FE │ 45 FE │
│ │ ApprovalGate (ORM + │ ~2 500 │ │ │ │
│ │ Pydantic + API + Svc) │ frontend │ │ │ │
│ │ Evidence.Adapter │ │ │ │ │
│ │ AgentRunModel (FE) │ │ │ │ │
│ │ ConfirmationCard ext. │ │ │ │ │
│ │ │ │ │ │ │
│ 037 │ DashboardQueryModel │ ~13 000 │ 9 │ 1.0 BE │ 360 BE │
│ │ Filters, QueryExecutor, │ backend │ │ 0.1 FE │ 30 FE │
│ │ Normalize, Compare │ ~2 000 │ │ │ │
│ │ Structure.Diff │ frontend │ │ │ │
│ │ Immutability.Detect │ │ │ │ │
│ │ Visual.Compare │ │ │ │ │
│ │ Release.ExtractBaseline │ │ │ │ │
│ │ Catalog.Load/Write │ │ │ │ │
│ │ VerificationRun (ORM+API)│ │ │ │ │
│ │ │ │ │ │ │
│ 038 │ ChecklistCatalog (19) │ ~10 000 │ 8 │ 1.0 BE │ 320 BE │
│ │ CapabilityMapper │ backend │ │ 0.1 FE │ 25 FE │
│ │ ScenarioCompiler │ ~1 500 │ │ │ │
│ │ Validator, Resolver │ frontend │ │ │ │
│ │ PackCompiler │ │ │ │ │
│ │ Capture.Dispatch │ │ │ │ │
│ │ Vlm.Analyze │ │ │ │ │
│ │ Human.Disposition │ │ │ │ │
│ │ Step templates │ │ │ │ │
│ │ │ │ │ │ │
│ 039 │ ApiClient, WorkspaceModel│ ~3 500 │ 8 │ 0.2 BE │ 70 BE │
│ │ EntryAction, Workspace │ backend │ │ 1.0 FE │ 560 FE │
│ │ Progress, ScenarioViews │ ~8 000 │ │ │ │
│ │ Parameters, Baseline │ frontend │ │ │ │
│ │ ArtifactPreview,Evidence │ │ │ │ │
│ │ ConfirmationBinding │ │ │ │ │
│ │ ReleaseVerification.* │ │ │ │ │
│ │ E2E tests │ │ │ │ │
│ │ │ │ │ │ │
│ Инт. │ Интеграционное тест-е │ — │ 2 │ 0.5 BE │ 40 BE │
│ │ Исправления, докум-я │ │ │ 0.5 FE │ 60 FE │
│ │ │ │ │ │ │
├──────┼──────────────────────────┼──────────┼────────────┼─────────┼──────────┤
│ИТОГО │ │ ~34 000 │ 20 календ. │ 1.5 BE │1 010 BE │
│ │ │ backend │ недель │ 1.0 FE │ 720 FE │
│ │ │ ~14 000 │ (5 мес.) │ 0.3 Ops │ 80 Ops │
│ │ │ frontend │ │ ─────── │ ──────── │
│ │ │ │ │ 2.8 FTE │1 810 net │
│ │ │ │ │ avg │2 260 full│
└──────┴──────────────────────────┴──────────┴────────────┴─────────┴──────────┘
Фазы и загрузка по ролям (календарный план)
Месяц 1 Месяц 2 Месяц 3 Месяц 4 Месяц 5
W1 W2 W3 W4 W5 W6 W7 W8 W9 W10 W11 W12 W13 W14 W15 W16 W17 W18 W19 W20
│ │ │ │ │
BE #1 ████████████████████████████████████████████████████████████████████░░░░████
036 AgentRun 036 AgentRun 038 Scenario 038 Scenario 038 Интегр.
foundations + gates Compiler+Val Capture+VLM PackComp +fixes
BE #2 ░░░░████████████████████████████████████████████████████████░░░░████
036 dep 037 QueryModel 037 Compare 037 StructDiff 037 Immutab. Интегр.
ready +Filters+Exec +Normalize +Visual +Release +fixes
FE #1 ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██████████████████████████████████
036 Model 036 стабилизация 039 DTOs 039 Workspace 039 Evidence Интегр.
+Cards фронта 036 стабильны +Params +Rel.Verify +E2E +fixes
Ops ░░░░░░░░░░████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░████████░░░░
Настройка CI + Testcontainers Мониторинг Релиз
верификаций +миграции
Условные обозначения:
████ — активная разработка (полная загрузка)
░░░░ — частичная загрузка / ожидание / поддержка
│ — граница недели
Простой разработчиков исключён: BE #2 стартует на неделю позже BE #1
(дожидается foundation 036), но его загрузка заполняется параллельными
задачами из 037, не зависящими от 036. FE получает стабильные DTO не
раньше недели 4, до этого работает над моделью AgentRun и карточками.
Расчёт человекочасов
Backend (суммарно 1.5 FTE):
BE #1 (1.0 FTE):
Недели 1–5 (036): 5 нед × 40ч = 200ч net → full ~250ч
Недели 6–14 (038): 9 нед × 40ч = 360ч net → full ~450ч
Недели 18–20 (инт): 3 нед × 20ч = 60ч net → full ~75ч
Итого BE #1: 620ч net / ~775ч full
BE #2 (1.0 FTE):
Недели 1–2 (ожидание 036 foundation): 2 нед × 10ч = 20ч
Недели 3–11 (037): 9 нед × 40ч = 360ч net → full ~450ч
Недели 18–20 (инт): 3 нед × 20ч = 60ч net → full ~75ч
Итого BE #2: 440ч net / ~550ч full
Всего backend: 1 060ч net / ~1 325ч full
Frontend (1.0 FTE):
Недели 1–3 (036 базовые компоненты): 3 нед × 40ч = 120ч
Недели 4–9 (стабилизация + ожидание DTOs): 6 нед × 15ч = 90ч
Недели 10–18 (039 полный цикл): 9 нед × 40ч = 360ч
Недели 19–20 (интеграция + E2E): 2 нед × 40ч = 80ч
Итого frontend: 650ч net / ~810ч full
DevOps (0.3 FTE):
Недели 4–5 (CI + Testcontainers): 2 нед × 20ч = 40ч
Недели 16–17 (мониторинг): 2 нед × 10ч = 20ч
Недели 18–19 (миграции + релиз): 2 нед × 15ч = 30ч
Итого ops: 90ч net / ~110ч full
═══════════════════════════════════════════════════════════════
ИТОГО: 1 800ч net / ~2 250ч full
12.0 FTE-месяцев
2.8 FTE × 5 календарных месяцев
═══════════════════════════════════════════════════════════════
Допущения и риски графика
| Фактор | Оценка | Влияние на человекочасы |
|---|---|---|
| Сложность Superset chart-data API (4.1.2) | Высокая | +15% к 037, если API нестабилен |
| Готовность VLM-провайдера (модель + промпт) | Средняя | +5% к 038, если требуется тюнинг промптов |
| Зрелость существующего GitService | Высокая (уже в проде) | Экономия ~10% на 037 (Catalog) |
| Наличие Testcontainers для Superset | Требует настройки | +3–5 дней DevOps на старте |
| Стабилизация DTOs между backend и frontend | Стандартный риск | Учтено в «ожидании DTOs» для FE |
| Рефакторинг по итогам code review | Стандартный | +25% в full-оценке |
Сравнение: MVP vs полный объём
┌─────────────────────┬──────────────────┬──────────────────────────┐
│ │ MVP │ Полный объём │
│ │ (3.5 месяца) │ (5 месяцев) │
├─────────────────────┼──────────────────┼──────────────────────────┤
│ FTE │ 1.5 BE + 0.5 FE │ 1.5 BE + 1.0 FE + 0.3 Ops│
│ Человекочасов (net) │ ~900ч │ ~1 800ч │
│ FTE-месяцев │ ~6.5 │ ~12.0 │
├─────────────────────┼──────────────────┼──────────────────────────┤
│ Что входит │ 036 полностью │ Всё из MVP + │
│ │ 037: метрическая │ 037: StructureDiff │
│ │ проверка без │ + Immutability │
│ │ StructureDiff │ + Visual baseline │
│ │ и визуальных │ 038: сценарии + VLM + │
│ │ baseline-ов │ capture + disposition │
│ │ 039: Agent │ 039: Agent Workspace + │
│ │ Workspace без │ Pipeline Views + │
│ │ Pipeline Views │ EvidencePanel + E2E │
├─────────────────────┼──────────────────┼──────────────────────────┤
│ Use cases │ UC-1 (ручная │ Все 7 use cases │
│ │ проверка) │ │
│ │ UC-2 частично │ │
│ │ (базовая метрика)│ │
└─────────────────────┴──────────────────┴──────────────────────────┘
Что это даёт бизнесу
До подсистемы:
- Проверка дашборда перед релизом: 30–40 минут ручной работы аналитика на каждый дашборд
- Детект изменения данных задним числом: 1–2 недели (пока кто-то случайно не заметит)
- Повторяемость проверок: нулевая (никто не помнит точные фильтры и значения)
- Аудит: «кажется, в мае было около 1,2 млн»
- Структурные регрессии: обнаруживаются в PROD пользователями
С подсистемой:
- Проверка дашборда перед релизом: 1 клик (автоматическая) + 5 минут на подтверждение результатов аналитиком
- Детект изменения данных задним числом: < 1 минуты (scheduled + ETL-triggered)
- Повторяемость: 100% (baseline.yaml в git, версионирован с дашбордом)
- Аудит: «01.06.2026, baseline v1.2.3, метрика X = 1 234 567.89, source_response_hash = sha256:abc, captured через Superset API»
- Структурные регрессии: блокируются на этапе деплоя в PREPROD
Следующие шаги
- Утверждение спецификации — ревью архитекторами и тимлидом
- Приоритизация — MVP: 036 + базовая 037 (метрическая проверка без StructureDiff и visual)
- Начало реализации — 036 Phase 1 (модели и миграции)
Документация по спецификациям: specs/036-agent-test-stabilization/ … specs/039-dashboard-scenario-ui/