Skip to content

feat(cli): untell humanize --html — per-span lock HTML report (Closes #30) - #44

Open
ssamba1 wants to merge 1 commit into
mainfrom
slice2-html
Open

feat(cli): untell humanize --html — per-span lock HTML report (Closes #30)#44
ssamba1 wants to merge 1 commit into
mainfrom
slice2-html

Conversation

@ssamba1

@ssamba1 ssamba1 commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Implements issue #30: untell humanize --html writes a self-contained, deterministic HTML report of the loop run to stdout — before/after text, pre/post scores, seed, whether it rewrote, the unified --diff payload, and a per-span lock annotation (via the explain/lock machinery, the same single source of truth as lock()).

  • Every dynamic value is HTML-escaped (fuzz-tested against <script>// injection — escaping is a defect under test, not a nicety).
  • No external assets: inline <style>, zero <script>//remote URLs.
  • --html --json emits a machine-readable envelope (format untell-html, version 1): report string + diff payload + pre/post + seed + rewrote; the --json error path stays parseable.
  • stdout is the clean document (progress suppressed, like --json), so ... --html > r.html yields a valid page.
  • Determinism, escaping, self-containment pinned by tests/test_humanize_html.py (15 tests).
  • AMBER (new CLI surface): queue entry added in .claude/human-queue.md (same commit). No RED file touched; loop result dict unchanged, so REST/MCP mirror nothing (surface parity already free-lists html as CLI-only).

Proof: 15/15 html tests, 119 targeted (diff/explain/surface), 135 CLI/enumeration, conformance humanize/loop, ruff whole-tree clean, real CLI subprocess produced a valid HTML doc (demo_report.html). Commit: 9dd4fcf — 'Closes #30'.

Copilot AI lite review requested due to automatic review settings August 17, 2026 22:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new untell humanize --html output mode to emit a deterministic, self-contained HTML report (optionally wrapped in a JSON envelope), including unified diff data and per-span lock annotations derived from the existing explain/lock machinery.

Changes:

  • Introduces --html CLI flag plus --html --json envelope output alongside existing --diff/--json behavior.
  • Adds an HTML renderer (render_humanize_html) that formats before/after text, scores, diff hunks, and locked-span annotations with escaping and inline CSS.
  • Adds a dedicated test suite for determinism, escaping, self-containment, and CLI contract behaviors.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
untell/scripts/run.py Adds the --html flag, suppresses progress on stdout for full-document modes, and emits either HTML or a JSON envelope containing HTML + diff.
untell/rich_output.py Implements HTML report rendering and supporting helpers (escaping, score/verdict formatting, diff/lock sections).
tests/test_humanize_html.py Adds tests for determinism, injection/escaping safety, self-containment expectations, and CLI surface contract for --html.
.claude/human-queue.md Records the new CLI surface as an AMBER queue entry with run evidence.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread untell/rich_output.py
Comment on lines +565 to +573
def _score_cell(score: dict, key: str, fmt: str = "{:.2f}") -> str:
"""A score dict value rendered safely, or \"—\" when absent/non-numeric."""
value = (score or {}).get(key)
if isinstance(value, (int, float)):
try:
return fmt.format(value)
except (ValueError, TypeError): # non-finite -> the dash, not a crash
return "—"
return "—"
Comment on lines +78 to +79
for marker in ("<script", "</script>", "<link ", "<img ", "src=", "href=", "http://", "https://"):
assert marker not in html, f"external-asset marker {marker!r} present in a self-contained report"
Comment thread untell/rich_output.py
Comment on lines +641 to +643
" .badge{display:inline-block;padding:1px 8px;border-radius:999px;font-size:12px;}"
" .badge.ok{background:var(--add);color:var(--addink);}"
" .badge.no{background:var(--del);color:var(--delink);}",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

untell humanize --html — HTML report with per-span lock explanations

2 participants