fix(notifications): HTML-safe card data render — fix <1м injection freezing the tracker (ORCH-095) #107
Reference in New Issue
Block a user
Delete Branch "feature/ORCH-095-bug-html-1-render-task-tracker"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
render_task_trackersends/edits the live tracker card withparse_mode=HTML._fmt_minutesreturns the literal<1мfor a sub-minute stage; interpolated raw into the HTML text, Telegram parsed<1мas an opening tag →editMessageText400 can't parse entities: Unsupported start tag "1м"→edit_telegramreturnsEDIT_FAILED→update_task_trackerearly-returns (anti-duplicate ORCH-087) → the card froze (incident ORCH-093,message_id 18854).The root class is wider than
<1м: every interpolated data value (durations, status label, model, effort, token/cost metrics) was inserted raw; only the title (esc_title) and the issue-link href/label were escaped.Change (per ADR-001)
_esc(x) = html.escape(str(x))(never-raise →"") wraps every DATA slot exactly once at the render boundary inrender_task_tracker/_stage_line: durations (_fmt_minutes/_capped_review_str), status label (_card_status_label), model (short_model_name), effort (_run_effort), tokens/cost (fmt_tokens/fmt_cost)._fmt_minutesstill returns<1м; escape on the boundary renders it visually identical (<1м), so the visible format is unchanged.num_html/plane_issue_link,link_for,_done_link, already-escapedesc_title) are not escaped → the issue number stays a clickable<a>tag; no double-escaping.200). No new code;edit_telegram/update_task_tracker/orphan ledger untouched → ORCH-087 anti-duplicate invariant preserved.STAGE_TRANSITIONS/QG_CHECKS/check_*/ notification transport / DB schema — untouched.Tests
New
tests/test_tracker_html_escape.py(TC-01..TC-11): boundary escape of sub-minute durations, never-raise_fmt_minutes/_esc, render without raw<1м, title special chars without double-escape, escaped status/model/effort, safe token/cost metrics, clickable-<a>+_done_linkmarkup regression, parse-safe edit payload, edit-in-place + transient-fail anti-duplicate, never-raise on broken inputs.Full
pytest tests/ -qgreen (1437);ruff checkclean.Docs
Architecture golden-source (
docs/architecture/internals.md§7,README.md) already carry the ORCH-095 HTML-safety invariant;CHANGELOG.mdupdated under[Unreleased].Refs: ORCH-095
🤖 Generated with Claude Code
efe8fd6383tocdc5e5c548