build(contracts): pin the shadcn contract to v2.3.0 so CI produces evidence again - #49
Merged
Conversation
…nd teeth dspack#35 merged the 32-component production contract, so check:sync — which follows dspack@main — went red on every branch here without a line of code changing. The harm is worse than a red check. check:sync runs in CI BEFORE the unit tests, so once upstream moved, unit tests, type checks and Playwright were all skipped rather than run. The repo stopped producing test evidence silently, which is precisely the condition under which renderer-parity work cannot be trusted — and renderer parity exists to make representation claims trustworthy. Following main would not widen coverage: the shadcn renderers, the emit profile and the scenario surfaces here were all built against v2.3.0, so it would break catalog builds and scenario surfaces, and couple unrelated work to a migration that cannot land until the emitter can represent the production catalog. So pin at the exact upstream commit this repo was built against (805732c, v2.3.0). The local copy is byte-identical to it — the same artifact dspack-emit pins, the same sha256 — so nothing is forked or re-authored to go green. A pin here is a stronger claim than tracking, not a weaker one. It verifies the pinned artifact's sha256 every run (a pinned ref must be immutable — a change means force-push or CDN mismatch, never a routine update), still fails on local drift, always reports how far behind main it sits so the 8-component contract can never read as current production coverage, and carries an explicit removal condition plus a tracking issue (#48). Verified all three states: clean pin exits 0; a mutated expected hash exits 1 with TAMPERED; a one-byte local edit exits 1. Refs #48 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the contracts sync-check to deliberately pin the shadcn contract to a specific upstream commit (v2.3.0) and documents the rationale/exit criteria, so CI can run downstream checks (tests/types/export) again instead of failing early on upstream drift.
Changes:
- Pin
shadcn-ui.dspack.jsonto the upstream v2.3.0 commit and verify pinned bytes via sha256 duringcheck-sync. - Add “pin” reporting that surfaces upstream drift relative to
mainwhile still enforcing local byte-equality. - Add documentation (
docs/CONTRACT-PIN.md) describing the pin, rationale, enforcement, and removal condition.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/contracts/scripts/check-sync.mjs | Adds pin+sha256 enforcement and drift reporting for the shadcn contract so check:sync can pass while still surfacing upstream movement. |
| docs/CONTRACT-PIN.md | Documents the shadcn contract pin decision, enforcement behavior, and removal criteria/issue link. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
49
to
+53
| local: join(root, "shadcn-ui.dspack.json"), | ||
| label: "shadcn-ui.dspack.json", | ||
| source: | ||
| "https://raw.githubusercontent.com/aestheticfunction/dspack/main/examples/shadcn-ui.dspack.json", | ||
| source: `${RAW}/805732c154f0f214721c9934a450b0edb2656c99/examples/shadcn-ui.dspack.json`, | ||
| note: "the shadcn contract — copy of the spec repo's source of truth", | ||
| // A DELIBERATE PIN, not staleness. dspack main now carries the |
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.
Narrow and mechanical. Independent of #47 (renderer parity) — this exists so that PR's tests actually run.
The problem
dspack#35 merged the 32-component production contract upstream, so
check:sync— which followsdspack@main— went red on every branch here without a line of code changing.The red check is not the real harm.
check:syncruns in CI before the unit tests:So the repo silently stopped producing test evidence. That is exactly the condition under which renderer-parity work cannot be trusted, and renderer parity exists specifically to make representation claims trustworthy.
Why not just follow main
The shadcn renderers, the emit profile and the scenario surfaces here were all built against v2.3.0 (8 components). The production contract has 32. Syncing forward would break catalog builds and scenario surfaces rather than widen coverage, and would couple unrelated work to a migration that cannot land until the emitter can represent the production catalog.
The pin
Pinned at
805732c(v2.3.0) — the exact upstream commit this repo was built against. The local copy is byte-identical to it (sha256 ca19f841…, the same artifactdspack-emitpins), so nothing is forked, copied or re-authored to go green.A pin here is a stronger claim than tracking, not a weaker one:
mainit sits, so the 8-component contract can never quietly read as current production coverage;Verification
All three states proven, not asserted:
TAMPERED …the PINNED artifact itself changedAstryx is untouched and still tracks
main.Removal
Only after the dspack-emit representation foundation lands and the profile migration completes — the emitter must be able to represent the production catalog before this repo consumes it. Gated on aestheticfunction/dspack-emit#28.
🤖 Generated with Claude Code