Skip to content

build(contracts): pin the shadcn contract to v2.3.0 so CI produces evidence again - #49

Merged
ryandmonk merged 1 commit into
mainfrom
build/contract-pin
Aug 5, 2026
Merged

build(contracts): pin the shadcn contract to v2.3.0 so CI produces evidence again#49
ryandmonk merged 1 commit into
mainfrom
build/contract-pin

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

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 follows dspack@main — went red on every branch here without a line of code changing.

The red check is not the real harm. check:sync runs in CI before the unit tests:

Contract copies match the authoritative dspack main (sync check)   ← fails here
Unit tests                                                          ← never runs
Type checks                                                         ← never runs
Static export / Playwright                                          ← never runs

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 artifact dspack-emit pins), so nothing is forked, copied or re-authored to go green.

A pin here is a stronger claim than tracking, not a weaker one:

  • verifies the pinned artifact's sha256 every run — a pinned ref must be immutable, so a change means force-push, history rewrite or CDN mismatch, never a routine update;
  • still fails on local drift, exactly as before;
  • always reports how far behind main it sits, so the 8-component contract can never quietly read as current production coverage;
  • carries an explicit removal condition and tracking issue (Migrate off the shadcn contract pin (v2.3.0 → production v3.0.0) #48).
in sync  astryx.dspack.json
PINNED   shadcn-ui.dspack.json  v2.3.0 @ 805732c (sha256 verified)
         upstream drift: main has moved (v3.0.0, 460066 bytes vs pinned 70040)
         NOT current production shadcn coverage — see docs/CONTRACT-PIN.md (#48)

Verification

All three states proven, not asserted:

state exit
clean pin 0
expected hash mutated (simulating a changed pinned artifact) 1, TAMPERED …the PINNED artifact itself changed
one byte appended to the local copy 1
restored 0

Astryx 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

…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>
Copilot AI lite review requested due to automatic review settings August 5, 2026 23:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.json to the upstream v2.3.0 commit and verify pinned bytes via sha256 during check-sync.
  • Add “pin” reporting that surfaces upstream drift relative to main while 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
@ryandmonk
ryandmonk merged commit 6151b72 into main Aug 5, 2026
2 checks passed
@ryandmonk
ryandmonk deleted the build/contract-pin branch August 5, 2026 23:26
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.

2 participants