Skip to content

feat: dist-diff — show reviewers what a PR changes in the built artifacts - #332

Draft
Peetee06 wants to merge 5 commits into
PostHog:mainfrom
Peetee06:feat/dist-diff
Draft

feat: dist-diff — show reviewers what a PR changes in the built artifacts#332
Peetee06 wants to merge 5 commits into
PostHog:mainfrom
Peetee06:feat/dist-diff

Conversation

@Peetee06

@Peetee06 Peetee06 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Why

A PR's source diff doesn't show its impact on this repo's actual product — the generated dist/ tree the wizard, MCP server, and plugin marketplace consume. Reviewers reconstruct that mapping in their heads.

Measured on #330 (8 added YAML lines): the real effect was a new wizard cliEntry, a new marketplace plugin, and a mirror entry — while a naive diff -r of the two builds reports 221 changed files, 216 of them noise (zip entry mtimes, manifest buildTimestamp).

What

npm run diff + two workflows that post a sticky PR comment with the normalized artifact delta, grouped by consumer surface. This is #330's comment, generated from its real build outputs:

Wizard surface

+ cliEntry creating-product-tours (role: skill)

Skill content ✓ unchanged

Marketplace

~ .claude-plugin/marketplace.json
+ plugins/
+   posthog-all/skills/creating-product-tours/
+     references/COMMANDMENTS.md
+     SKILL.md
+   posthog-product-tours/
+     .claude-plugin/plugin.json
+     skills/all/
+       references/COMMANDMENTS.md
+       SKILL.md

Agents ✓ unchanged · MCP manifest ✓ unchanged

Skills-repo mirror

~ push-manifest.json

The workflow step summary carries the full report with content-level hunks (one per unique delta, so a shared-doc change fanning into 68 variant zips shows its hunk once).

Design invariants

  • Totality: every file under dist/ is compared; unknown future artifact types degrade to byte comparison — noise at worst, never silently skipped.
  • Self-check: two builds of the same ref must produce an empty normalized diff. Runs on pushes to main and on PRs touching scripts/, package.json, the lockfile, or the workflow — content PRs can never go red here. On failure the report still posts (warning-stamped) before the job fails.
  • Baseline: merge-base vs head, built in one job sharing one .docs-cache, so upstream doc drift can't appear in the diff.
  • Fork parity: the diff job runs with contents: read only; a minimal workflow_run job posts the sticky comment, verifying the artifact's PR number against the run's head SHA.
  • Comment stays ≤40 lines via fan-out grouping (identical-delta, same-files-touched, added-directory); deps added: fflate (same zip library the MCP server uses on these archives) and diff (jsdiff), both dev-tier.

Verification

  • 292 tests pass (15 new, including golden fixtures replaying #330's shape and the fan-out/collision regressions).
  • Validated against 10 recent merged PRs by building each merge-base/merge pair and rendering both reports: zero errors, every comment within budget, CI-only PRs (#310, #323) correctly report zero artifact changes.

A follow-up issue will propose a GitHub-native alternative for the full report (push normalized base/head trees to a throwaway ref and let GitHub's commit view render the diff) — it would delete the hunk-rendering code here but needs a maintainer call on contents: write and ref hygiene.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GDjuSAs927XvcyziFJk865

Peetee06 and others added 5 commits August 9, 2026 14:37
A PR's source diff doesn't show its effect on the built artifacts: an
8-line config change can add a wizard cliEntry, a marketplace plugin,
and a mirror entry, while a naive diff of two builds reports 221 changed
files of which 216 are noise (zip entry mtimes, manifest buildTimestamp).

dist-diff compares two normalized dist/ trees and reports the true
artifact delta per consumer surface, as a sticky PR comment (posted by a
minimal privileged workflow_run job so fork PRs get identical treatment)
plus a full report with content hunks in the step summary. A twice-build
self-check guards the normalization on pipeline-touching PRs and main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDjuSAs927XvcyziFJk865
- Root-level files no longer fold into a nameless directory bucket (the
  empty-dir key was a string-prefix of every same-kind key)
- Budget truncation now trims inside diff blocks, so surface headers and
  the "✓ unchanged" assertions always survive; removes the old tail-cut
  that could clobber a line and leave an open fence
- Content-hunk size gate moved to decompressed inner-entry size — a tiny
  archive holding a huge entry no longer reaches the differ unchecked
- Full report diffs added/removed files against the empty side
- Corrupt-zip failures now name the offending file (still fail loudly:
  a zip our own build wrote but can't read back is a broken build)
- Dedupe delta-key and inner-suffix construction; fix stale --self-check
  reference in the module header

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDjuSAs927XvcyziFJk865
An identical-delta fan-out is one content change that happens to land in
many archives — so the full report now leads with what changed (the
shared inner file) and the hunk itself, and collapses the member list
into <details>. Replaces the per-surface tree + hunks-in-details layout
where 68 zip lines repeated the same inner path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDjuSAs927XvcyziFJk865
skills-mcp-resources.zip is derived (manifest + every skill zip), so its
diff repeats what the report already shows. Cross-check each inner change
against the reported constituent changes: consistent collapses to one
verified summary line; an unexplained inner change — a broken bundling
step — goes loud with a warning in both reports.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDjuSAs927XvcyziFJk865
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