06. HTML Render¶
Purpose¶
Document HTML rendering as a pure view layer over canonical report data.
Public surface¶
- Main renderer:
codeclone/report/html/assemble.py:build_html_report - Package entrypoint:
codeclone/report/html/__init__.py:build_html_report - Context shaping:
codeclone/report/html/_context.py - Escaping helpers:
codeclone/report/html/primitives/escape.py - Snippet/highlight helpers:
codeclone/report/html/widgets/snippets.py - Sections/widgets/assets:
codeclone/report/html/sections/*,codeclone/report/html/widgets/*,codeclone/report/html/assets/* - User-facing copy catalog:
codeclone/report/messages/*(glossary, suggestions, explainability, overview, security, chrome)
Data model¶
Inputs to the renderer:
- canonical
report_document(preferred path) - shared
report_meta - optional runtime snippet sources for code excerpts
Output:
- one self-contained HTML string
Contracts¶
- HTML must not recompute detection semantics; it renders facts from report/core layers.
- Provenance panels mirror canonical report/meta facts.
- Overview, Review, Quality, Module map, Suggestions, Dead Code, Dependencies, and Clones tabs are projections over canonical report sections.
- The
Reviewtab (between Overview and Clones) is render-only and is the guided entry point for triaging findings. It draws the precomputedderived.review_queue— a prioritized, cross-family actionable queue — as a list of shared finding cards. The reviewed state (per finding id, persisted inlocalStorage), the progress bar, and the severity/family filters are client-side UX over those rendered facts; it recomputes nothing. TheOverviewlaunchpad surfaces the queue total plus severity counts and jumps into this tab viadata-goto-tab; the queue is empty (and the launchpad hidden) when there are no suggestions, mirroringderived.suggestionsexactly. codeclone/report/html/widgets/cards.py:finding_cardis the single card chrome shared by the Suggestions, Review, and Structural Findings surfaces — one severity stripe + badge + meta/body/details/actions shell, so per-surface markup is not duplicated.- Quality covers per-function/class metrics (Complexity, Coupling, Cohesion) plus
report-only subtabs such as
Coverage JoinandSecurity Surfaces; these remain factual projections over canonical metrics families rather than HTML-only analysis. Quality does not host the overloaded-modules profile — that module-level view lives in theModule maptab. - The
Module maptab (between Quality and Dependencies) is render-only and is the single home for module-level responsibility. It draws the precomputedderived.module_mapgraph views and unwind-candidate triage, plus the fulloverloaded_modulesprofile (stat cards + table) read directly frommetrics.families.overloaded_modules. It re-samples nothing and adds no health dimension — the SVG may show a deterministic sample on large repositories while the unwind and overloaded tables stay full-size. ThePackages/Modulestoggle swaps the two precomputed graphs without recomputation. The graph block shows "Dependency graph is not available." when the dependencies family is skipped; the overloaded-modules section renders whenever that metrics family is present, independent of graph availability. - IDE deep links are HTML-only UX over canonical path/line facts.
- Missing snippets or optional meta fields render safe factual fallbacks rather than invented data.
Refs:
codeclone/report/html/assemble.py:build_html_reportcodeclone/report/html/sections/_review.py:render_review_panelcodeclone/report/html/widgets/cards.py:finding_cardcodeclone/report/html/sections/_clones.py:_render_group_explanationcodeclone/report/html/sections/_module_map.py:render_module_map_panelcodeclone/report/html/widgets/dep_graph_layout.pycodeclone/report/html/sections/_meta.py:render_meta_panelcodeclone/report/html/assets/js.py:_IDE_LINKScodeclone/report/overview.py:materialize_report_overview
Invariants (MUST)¶
- User/content fields are escaped before insertion into HTML.
- Missing file snippets render explicit fallback blocks.
- Novelty badges reflect baseline trust and per-group novelty flags.
- Suppressed dead-code rows render only from report suppression payloads.
- Path-link
data-fileanddata-lineattributes are escaped before insertion.
Refs:
codeclone/report/html/primitives/escape.py:_escape_htmlcodeclone/report/html/widgets/snippets.py:_render_code_blockcodeclone/report/html/widgets/tables.py
Failure modes¶
Refs:
codeclone/report/html/widgets/snippets.py:_FileCachecodeclone/report/html/widgets/snippets.py:_try_pygments
Determinism / canonicalization¶
- Section and group ordering follow sorted canonical report inputs.
- Metadata rows are built in fixed order.
Refs:
codeclone/report/html/assemble.py:build_html_reportcodeclone/report/html/sections/_meta.py:render_meta_panel
Locked by tests¶
tests/test_html_report.py::test_html_report_uses_core_block_group_factstests/test_html_report.py::test_html_report_escapes_meta_and_titletests/test_html_report.py::test_html_report_escapes_script_breakout_payloadtests/test_html_report.py::test_html_report_missing_source_snippet_fallbacktests/test_html_report.py::test_html_and_json_group_order_consistenttests/test_html_report.py::test_html_report_quality_includes_security_surfaces_subtab
Non-guarantees¶
- CSS, layout, and interaction details may evolve without a schema bump.
- IDE deep link behavior depends on local IDE installation and protocol handlers.
