Files
orchestrator/docs/work-items/ORCH-095/10-tech-risks.md
claude-bot 30e194c254
All checks were successful
CI / test (push) Successful in 42s
architect(ET): auto-commit from architect run_id=526
2026-06-09 23:56:33 +03:00

5.5 KiB
Raw Blame History

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> превращается в &lt;a&gt;, номер задачи перестаёт быть кликабельным (регресс 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 не требуется; возврат в анализ не требуется (ТЗ реализуемо без нарушения архитектурных принципов).