Files
orchestrator/docs/work-items/ORCH-095/12-review.md

5.8 KiB
Raw Permalink Blame History

verdict, work_item, stage, author_agent, status, created_at, model_used, type, work_item_id, version
verdict work_item stage author_agent status created_at model_used type work_item_id version
APPROVED ORCH-095 review reviewer approved 2026-06-10 claude-opus-4-8 review ORCH-095 1

Review ORCH-095

Summary

Фикс HTML-инъекции <1м в live-карточке трекера. Точечное, аддитивное, never-raise изменение в индикативном слое (src/notifications.py): новый модуль-локальный хелпер _esc(x) = html.escape(str(x)) оборачивает каждый data-слот (dur/_fmt_minutes/_capped_review_str, status_label, model, effort, токены/стоимость) ровно один раз на границе рендера (render_task_tracker/_stage_line); markup-слоты (num_html/link_for/_done_link/ уже-экранированный esc_title) не трогаются. Источники (_fmt_minutes, src/usage.py) остаются HTML-агностичными.

Проверены все четыре оси. Реализация соответствует ТЗ (FR-1…FR-5) и ADR-001 (D1…D6) буквально; все 5 AC выполнены. STAGE_TRANSITIONS / QG_CHECKS / check_* / схема БД / транспорт нотификаций — не тронуты (git diff пуст по src/stages.py, src/qg/, src/stage_engine.py, src/db.py). Полный регресс pytest tests/ -q зелёный (1437 passed), новый tests/test_tracker_html_escape.py (TC-01…TC-11) — зелёный.

Соответствие осям:

  1. ТЗ / AC — FR-1/AC-1 (<1м&lt;1м на границе, источник не меняется), FR-2/AC-2 (все D-слоты экранированы — сверено по коду стр. 471/517-523/529/594/607/614-615/620-621/629), FR-3/AC-3 (M-слоты не экранированы, двойного экранирования нет), FR-4/AC-4 (авто-восстановление следующим рендером, без рискованной переклассификации EDIT_FAILED — корректно, защищает инвариант ORCH-087), FR-5/AC-5 (never-raise + зелёный регресс + CHANGELOG). ✓
  2. ADR + трассировка — реализация 1:1 с ADR-001 (escape на границе рендера, не в источнике; M-слоты неприкосновенны). Блоки с маркерами ORCH-042/067/087/091 правлены аддитивно: код лишь оборачивает уже вычисленные D-значения в _esc, не меняя состав строк/порядок/логику подавления и суммирования — инварианты сохранены по построению. Сквозной adr-NNNN обоснованно не заведён (локальный indication-only фикс). ✓
  3. Качество кода_esc с docstring и never-raise; тесты содержательные (11 TC покрывают каждый AC, включая регресс кликабельного <a href>-номера, _done_link и анти-дубль ORCH-087 на транзиентном фейле). ✓
  4. Документация — обновлены в том же PR: CHANGELOG.md, docs/architecture/README.md (блок Notifications/Live-tracker), docs/architecture/internals.md §7, ADR-001. ✓

Findings

P0 — Blocker

  • Нет.

P1 — Must fix

  • Нет.

P2 — Should fix

  • Нет.

P3 — Nice-to-have

  • attempt (f"… попытка {attempt} …", ~стр. 572) и статичные лейблы стадий (_TRACKER_STAGES/_BRD_LABEL) не проходят через _esc. ADR-001 D1 упоминает их в категории D «ради единообразного инварианта», но attempt — всегда int (len(agent_runs)), а лейблы — статичные константы → фактической поверхности инъекции нет, расхождение безвредно. Не блокирует; можно унифицировать при будущем касании блока (оставляю на усмотрение, не требую правки).

Документация

Обновлена полностью в том же PR — требование правила 6 (CLAUDE.md) выполнено:

  • CHANGELOG.md — детальная запись ORCH-095 (механизм бага, D1D5, восстановление, трассировка, тесты).
  • docs/architecture/README.md — компонент «Notifications / Live-tracker» дополнен абзацем ORCH-095 (data/markup-слоты, инвариант экранирования на границе, ссылка на ADR).
  • docs/architecture/internals.md §7 — новая подсекция «HTML-безопасность данных карточки (ORCH-095)».
  • docs/work-items/ORCH-095/06-adr/ADR-001-html-safe-card-data-render.md — архитектурное обоснование (выбор точки экранирования, альтернативы, последствия).

Пункт README.md «Известные ограничения» данным фиксом не закрывается (баг корректности, не числился в витрине ограничений) → обновление обзорной витрины (ORCH-079) не требуется.

Вывод: src/ изменён — документация обновлена синхронно. P0 «документация не обновлена» не применяется.