5.5 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-095 | architecture | architect | accepted | 2026-06-09 | claude-opus-4-8 |
10 — Технические риски: ORCH-095 — HTML-безопасность данных live-карточки
Work Item: ORCH-095 · Repo: orchestrator · Стадия: architecture
Информационный (гейтом не парсится). Перечисляет риски реализации и их митигейшн.
Реестр рисков
| ID | Риск | Вер. | Влия. | Митигейшн |
|---|---|---|---|---|
| TR-1 | Двойное экранирование уже-экранированных полей (esc_title, href/label внутри plane_issue_link) → < в выводе, визуальный мусор / регресс AC-2 |
Сред. | Сред. | D1/D5: явный реестр M-слотов (markup) — через _esc НЕ проходят; esc_title остаётся единственной точкой escape заголовка; тест AC-2 ассертит отсутствие < |
| TR-2 | Случайное экранирование разметки-обёртки (num_html/link_for/_done_link) → <a> превращается в <a>, номер задачи перестаёт быть кликабельным (регресс BR-4/AC-3) |
Низ. | Выс. | D5: M-слоты неприкосновенны; регресс-тесты test_tracker_issue_link.py/test_notify_issue_links.py/test_telegram_tracker.py зелёные; AC-3 проверяет наличие валидного <a href> в выводе |
| TR-3 | Пропущен новый/существующий D-слот (забыли обернуть _esc) → инъекция возвращается на другом поле |
Низ. | Сред. | D3 defence-in-depth (обернуть ВСЕ D-поля разом); тест-инвариант AC-2 рендерит карточку с < > & в данных и ассертит отсутствие сырых спецсимволов из данных в выводе (свойство render_task_tracker, не пер-поле) |
| TR-4 | Регресс never-raise: _esc(str(x)) на «битом» входе (объект с падающим __str__) бросает исключение в пути рендера (нарушение NFR-1) |
Низ. | Сред. | FR-5: _esc сам never-raise (try/except → fallback-строка); путь render_task_tracker/update_task_tracker уже обёрнут try/except (строки 654/745); тест AC-5 с «битым» входом |
| TR-5 | Застрявшая карточка не восстановилась (задача завершилась до деплоя → нет будущего рендера) | Сред. | Низ. | Принятая known-limitation (D4): авто-recovery работает только при предстоящем переходе стадии; вне окна — Telegram-48ч (унаследовано ORCH-087); BR-5 ограничен карточками в окне |
| TR-6 | Скрытая регрессия инвариантов соседних маркеров (ORCH-087 анти-дубль, ORCH-091 суммирование _stage_line) при правке тела _stage_line/render_task_tracker |
Низ. | Выс. | D6: изменение аддитивно (лишь оборачивает уже вычисленные значения в _esc), не меняет состав/порядок строк, логику подавления откатов и суммирования; полный регресс pytest tests/ -q зелёный (NFR-2) |
| TR-7 | Self-hosting: фикс деплоится на общий прод-инстанс (затронуты и enduro-trails) | Низ. | Сред. | NFR-3: изменение только слоя рендера; STAGE_TRANSITIONS/QG_CHECKS/схема БД не тронуты; обязательная страховка deploy-staging (8501) перед прод-деплоем; прод orchestrator не рестартится в рамках разработки |
Сводный вывод
Доминирующий класс рисков — регресс рендера (двойное экранирование / случайное экранирование
разметки / пропущенный D-слот), полностью покрываемый тест-инвариантом AC-2 + существующими
регресс-тестами трекера (AC-3/AC-5). Изменение локализовано в src/notifications.py (слой
рендера уведомлений), аддитивно к маркерам ORCH-042/067/087/091, не затрагивает машину стадий,
Quality Gates, схему БД, транспортные примитивы и режимы трекера. Остаточный риск для
прод-конвейера (self-hosting) — низкий: контракт never-raise сохранён, откат — обычный revert
PR без операций над данными. Эскалация arch:major-change не требуется; возврат в анализ
не требуется (ТЗ реализуемо без нарушения архитектурных принципов).