feat(engine): trace report generation — Markdown + HTML#47
Merged
Conversation
Add src/ocpp/report.zig: render an AnalysisResult as a Markdown report and a self-contained HTML report, mirroring the toolkit's reporter (the same six sections — header, session overview, timeline summary, failures, suggested next steps, event appendix). Add src/ocpp/summarizer.zig (ADR-0003 parity) and a SessionSummary type to derive the per-session projections the report consumes. Harden the untrusted-input path beyond the toolkit: every trace-derived value is escaped on BOTH outputs (HTML entities for HTML; table/line-structural chars for Markdown, which the toolkit's Markdown reporter does not escape), and every list section is bounded so a dataset-scale trace (ADR-0007) can't produce an unbounded document. The header still reports the true totals. Includes an epoch-ms to ISO-8601-UTC formatter (std.time.epoch); the engine had only ISO-to-epoch before. Pure and headless — no file I/O in the module; the caller owns the allocator. Closes #41.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
feat(engine): Markdown + HTML trace report generation (S4 #41), plus thesession summarizer it consumes.
Closes #41.
Changes
src/ocpp/report.zig—generateMarkdownReport/generateHtmlReportoveran
AnalysisResult, mirroring the toolkit'sreporter/{markdown,html}.ts: thesame six sections (header, session overview, timeline summary, failures,
suggested next steps, event appendix). Self-contained HTML (inline CSS ported
from the toolkit — no external assets). Includes an epoch-ms → ISO-8601-UTC
formatter (
std.time.epoch); the engine only had ISO → epoch before.src/ocpp/summarizer.zig+types.SessionSummary— ADR-0003 paritywith
core/summarizer.ts: per-session event count, duration, Call actionsequence, and the count of failures touching the session. The diff (feat(engine): semantic trace diff #43) reuses it.
ocpp.zig(exports + test discovery); CURRENT_STATE updated.Hardening beyond the toolkit (untrusted input)
trace-derived value is escaped on HTML and Markdown, so a hostile payload can't
inject markup (HTML) or break a table/line (Markdown). Enum wire strings
(direction/type/severity/status/code) are the only unescaped output.
rendered list is capped (appendix 1000, sessions/failures 500) with a truncation
note. The header still reports true totals.
Tests
98/98 headless tests pass (
native test -Dplatform=null);native check --strictclean;
zig fmtclean. New coverage: both formats over the clean and failed-authfixtures, exact epoch→ISO formatting, HTML self-containment (no external asset
refs), hostile content escaped on both paths, list-section bounds, and the
empty-analysis placeholders.
Scope notes
affordance belong to the CLI (feat(cli): headless CLI subcommands + parity table #45); a save dialog rides the same runner-eject as
feat(ui): interactive open — native dialog + drag-drop (ejected runner) #33.
byte-identical across the two implementations.