Skip to content

feat(report): emit self-contained HTML validation report + report.json#74

Merged
dadachi merged 1 commit into
mainfrom
feat/validation-report
May 22, 2026
Merged

feat(report): emit self-contained HTML validation report + report.json#74
dadachi merged 1 commit into
mainfrom
feat/validation-report

Conversation

@dadachi
Copy link
Copy Markdown
Contributor

@dadachi dadachi commented May 22, 2026

What

Implements steps 3–7 of docs/validation-report.md (steps 1–2 shipped in #73). Every run now emits, into out/<slug>/:

  • report.json — the machine-readable RunReport (for CI gating, MCP, future web product)
  • validation-report.html — a single self-contained file (screenshots base64-embedded, CSS inlined, no JS framework, no network) summarizing all validation layers + the reviewer

Report contents

Overall verdict badge → gate strip → platform×layer matrix → Layer 1 leftover-token findings → Layer 2 command/duration/stderr → Layer 3 home-screen screenshots + rubric rationales (incl. Stage 2 filmstrip) → reviewer contract diff → domain/rename-plan appendix → reproduce command.

Design

  • render.ts is purerenderReport(report, assets) → string, no I/O, no clock. Deterministic and golden-file testable. All interpolated text is HTML-escaped.
  • collect.ts owns I/ObuildRunReport (pure assembly), resolveAssets (base64-embed or copy to report-assets/), writeReport.
  • dispatch returns DispatchResult = JudgeResult & { report, reportPaths } — a superset, so existing result.overallPass/result.summary consumers (CLI, MCP, tests) are unaffected. Report writing defaults off in stub mode, so the test suite never writes into ./out.
  • CLI flags: --no-report, --report-format=html|json|both, --report-embed=true|false, --report-open; prints a file:// path.
  • MCP: returns report + reportHtmlPath/reportJsonPath in structuredContent.
  • src/version.ts dedups the readPackageVersion helper that was duplicated in mcp.ts.

Tests

  • Pure renderer: findings, stderr, reviewer diff, rename plan, HTML escaping, and the empty-platforms summary fallback (stub runs).
  • writeReport round-trip: asserts the HTML is self-contained — embeds a data: URI and leaks no tmp/ paths and no external URLs.
  • embed=false externalization to report-assets/, and buildRunReport assembly.
  • npm run ci green — build + typecheck + 46/46 tests pass.

A rendered sample (mixed pass/fail run) was eyeballed end-to-end with real generated screenshots.

🤖 Generated with Claude Code

Implements steps 3-7 of docs/validation-report.md (step 1-2 shipped in
#73). Every run now writes out/<slug>/report.json (machine-readable
RunReport) and validation-report.html (self-contained, screenshots
base64-embedded) summarizing all validation layers + the reviewer.

- src/report/model.ts   — RunReport / RunMeta / RepairAttempt / AssetMap
- src/report/render.ts   — renderReport(report, assets): pure, no I/O;
                           gate strip, platform×layer matrix, Layer 1
                           findings, Layer 2 stderr, Layer 3 screenshots
                           + rubric rationales (incl. Stage 2 filmstrip),
                           reviewer diff, rename-plan appendix, reproduce
                           footer. HTML-escaped throughout.
- src/report/theme.ts    — inline brand CSS (matches social-preview)
- src/report/collect.ts  — buildRunReport (pure assembly), resolveAssets
                           (embed as data: URI, or copy to report-assets/),
                           writeReport (report.json + HTML)
- src/version.ts         — shared readPackageVersion (dedups mcp.ts copy)
- dispatch: records timing, assembles + writes the report, returns
  DispatchResult = JudgeResult & { report, reportPaths }. Writing
  defaults off in stub mode so the test suite never touches ./out.
- index: --no-report / --report-format / --report-embed / --report-open
  flags; prints a file:// path. mcp: returns report + html/json paths in
  structuredContent.

Tests: pure renderer assertions (findings, stderr, diff, rename plan,
HTML escaping, empty-platforms summary fallback), writeReport round-trip
(self-contained — asserts no tmp/ paths and no external URLs leak),
embed=false externalization, and buildRunReport assembly. 46/46 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dadachi dadachi merged commit 3730863 into main May 22, 2026
1 check passed
@dadachi dadachi deleted the feat/validation-report branch May 22, 2026 09:27
dadachi added a commit that referenced this pull request May 22, 2026
…rt (#75)

Finishes the validation-report story (follows #74).

- index: the CLI now exits non-zero when overallPass is false, so CI
  steps and shell `&&` chains catch a failed run. New --exit-zero flag
  opts out (e.g. when you only want the report). parseArgs is exported
  and unit-tested.
- README: new "Validation report" section documenting validation-report.html
  + report.json, the out/<slug>/ layout, the CI exit-code behavior, and
  the --no-report / --report-format / --report-embed / --report-open /
  --exit-zero flags.

Tests: parseArgs flag parsing (incl. --exit-zero, invalid format
ignored, defaults). 49/49 pass.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dadachi added a commit that referenced this pull request May 22, 2026
…kflow (#76)

Adds section 10 to docs/validation-report.md covering how to render and
visually verify validation-report.html:

- Path A — Playwright MCP (interactive, inside Claude Code): local-scope
  `claude mcp add playwright`, restart to load tools, then browser_navigate
  (file:// URL) + browser_take_screenshot. Note it's a maintainer
  convenience, not part of the pipeline (device shots use mobile-mcp).
- Path B — Playwright CLI (headless, no MCP, CI-friendly):
  `npx -y playwright@latest screenshot --full-page file://… report.png`,
  no project dependency added.

Also marks section 9 as shipped (#73/#74/#75).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant