Re-pin vendored core to dspack-gen v0.1.1; golden-context + pin-drift checks#21
Conversation
…drift checks The vendored core bundle was pinned at f651433, predating dspack-gen 0.1.1's generation-schema fixes for grammar-constrained decoders, so the published 0.3.0 served a schema that declared node text before props and degraded array-typed contract props to strings. - Re-pin the devDependency to 374e1cd, the v0.1.1 tag commit. Tag-pinned is the documented default posture: the vendored core corresponds exactly to a published dspack-gen version. - Golden-context test byte-compares get-generation-context output against dspack-gen's compiler golden (synced byte copy, tracked in check-sync). Byte-level on purpose: grammar decoders enforce property order, which deepEqual cannot see. Fails on the old bundle at schema line 40 (text before props); passes on 0.1.1. - check-core-pin.mjs + CI job: blob-exact src/core comparison (trees API; the compare API caps at 300 files and silently truncates) between the pin and dspack-gen's latest release tag. *.test.ts excluded — the documented escape for ahead-of-release pins. API failure warns and passes; real drift fails. - Release workflow: npm trusted publishing on version tags, mirroring dspack-gen (requires one-time trusted-publisher setup on npmjs.com). - 0.3.1, CHANGELOG. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates ds-mcp’s vendored @aestheticfunction/dspack-gen/core pin to the v0.1.1 tag commit and adds guardrails to prevent future schema/semantic drift by introducing a byte-oriented golden-context test plus a CI pin-drift check. It also prepares the 0.3.1 release (including a changelog entry and a tag-triggered trusted-publishing workflow).
Changes:
- Re-pin
@aestheticfunction/dspack-gento the v0.1.1 tag commit and bump ds-mcp to0.3.1(with CHANGELOG shipped). - Add a golden-context test + tracked golden fixture synced via
scripts/check-sync.mjs. - Add
scripts/check-core-pin.mjsand wire it into CI; add a release workflow for npm trusted publishing on version tags.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/tests/generation-context-golden.test.ts | Adds a golden-context test to pin get-generation-context output against dspack-gen’s golden. |
| src/tests/fixtures/shadcn.destructive-action.context.json | Adds the synced golden generation-context fixture used by the new test. |
| scripts/check-sync.mjs | Extends the sync manifest to include the new golden context fixture. |
| scripts/check-core-pin.mjs | Adds a GitHub-API-based script to detect drift between the pinned vendored core and latest dspack-gen release tag. |
| .github/workflows/test.yml | Runs the new core pin drift check as a separate CI job. |
| .github/workflows/release.yml | Adds a tag-triggered npm trusted publishing workflow with version/tag guard and pre-publish tests. |
| package.json | Bumps version to 0.3.1, includes CHANGELOG in published files, and re-pins dspack-gen devDependency commit. |
| package-lock.json | Updates the lockfile to reflect the new dspack-gen pin and dependency graph changes. |
| CHANGELOG.md | Documents 0.3.1 changes, including the re-pin, golden test, and drift check. |
| README.md | Updates documentation around the tag-pinned posture and the two drift checks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * What ds-mcp serves from get-generation-context MUST be what dspack-gen's | ||
| * compiler computes for the same contract and intent — byte for byte after | ||
| * JSON serialization (the wire shape an MCP client receives). The golden is | ||
| * a byte-synced copy of dspack-gen's own compiler golden |
| const at = s.findIndex((line, i) => line !== g[i]); | ||
| assert.fail( | ||
| `generation schema drifted from the dspack-gen golden — the vendored core pin should move.\n` + | ||
| `first divergence at schema line ${at}:\n served: ${s[at]}\n golden: ${g[at]}`, | ||
| ); |
| const response = await fetch(`${API}${path}`, { | ||
| headers: { accept: "application/vnd.github+json", "user-agent": "ds-mcp-check-core-pin" }, | ||
| }); |
|
Post-publish verification (PHASE-NEXT WS0, task 0.6), run against the registry artifact:
WS0 exit criteria are met. dspack-studio#13 (FM-11) is now unblocked: its take-home copy references 🤖 Generated with Claude Code |
Summary
PHASE-NEXT WS0 (dspack-studio docs/PHASE-NEXT.md): the vendored
@aestheticfunction/dspack-gen/corebundle was pinned atf651433, which predates the 0.1.1 generation-schema fixes, so the published ds-mcp 0.3.0 serves a pre-fix schema fromget-generation-context. This PR re-pins to the v0.1.1 tag commit, adds the golden-context honesty test and a pin-drift CI check, and preps the 0.3.1 release with trusted publishing.Fail-first evidence
The new golden-context test, run against the OLD pin (
f651433bundle), fails with the exact pre-0.1.1 signature:After the re-pin (same assertions, unchanged):
✔ get-generation-context serves exactly dspack-gen's golden context (schema semantics pinned, byte-level)— 94/94 pass.Two findings from writing it fail-first:
textbeforeprops), which grammar-constrained decoders enforce but deepEqual cannot see. The test therefore compares serialized bytes, and the comment says why.Changes
package.json: devDependency pinf651433→374e1cd(v0.1.1 tag commit; verified the onlysrc/corechange past the tag is a test file the vendor bundle never ships); version 0.3.1; CHANGELOG added and shipped.src/tests/generation-context-golden.test.ts: byte-level golden comparison of{system, schema, fewshot}against dspack-gen's own compiler golden.src/tests/fixtures/shadcn.destructive-action.context.json: synced byte copy of the golden, tracked inscripts/check-sync.mjs(fetched through the real sync pipeline).scripts/check-core-pin.mjs+ CI job: fails loudly when the pin's shippedsrc/corefiles differ from dspack-gen's latest release tag;*.test.tsexcluded (documented escape for ahead-of-release pins); API failures warn and pass (report-only posture). Verified both ways: green on the tag pin, red namingsrc/core/generation-schema.tson the old pin..github/workflows/release.yml: npm trusted publishing on version tags, mirroring dspack-gen's workflow (Node 24 for npm ≥ 11.5 OIDC). Owner setup required before tagging: register the trusted publisher on npmjs.com (package → Trusted publisher: repoaestheticfunction/ds-mcp, workflowrelease.yml).Validation
npm test: 94/94 (build is pretest, so the suite validates the rebuilt vendor bundle)node scripts/check-sync.mjs: 4/4 in sync (including the new golden)node scripts/check-core-pin.mjs: in sync (pin == v0.1.1 tag)Release sequencing (after merge)
v0.3.1on main → release workflow publishes.get-generation-contextbyte-compared against the golden — recorded in the release notes.dspack-studio's take-it-home workstream (FM-11) references ds-mcp only at 0.3.1 or later.
🤖 Generated with Claude Code