Skip to content

Re-pin vendored core to dspack-gen v0.1.1; golden-context + pin-drift checks#21

Merged
ryandmonk merged 1 commit into
mainfrom
fix/repin-dspack-gen-core-0.1.1
Jul 14, 2026
Merged

Re-pin vendored core to dspack-gen v0.1.1; golden-context + pin-drift checks#21
ryandmonk merged 1 commit into
mainfrom
fix/repin-dspack-gen-core-0.1.1

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

Summary

PHASE-NEXT WS0 (dspack-studio docs/PHASE-NEXT.md): the vendored @aestheticfunction/dspack-gen/core bundle was pinned at f651433, which predates the 0.1.1 generation-schema fixes, so the published ds-mcp 0.3.0 serves a pre-fix schema from get-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 (f651433 bundle), fails with the exact pre-0.1.1 signature:

✖ get-generation-context serves exactly dspack-gen's golden context (schema semantics pinned, byte-level)
  AssertionError [ERR_ASSERTION]: generation schema drifted from the dspack-gen golden — the vendored core pin should move.
  first divergence at schema line 40:
    served:             "text": {
    golden:             "props": {

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:

  • deepEqual passes on the old pin. The 0.1.1 divergence on this contract is property ORDER (text before props), which grammar-constrained decoders enforce but deepEqual cannot see. The test therefore compares serialized bytes, and the comment says why.
  • GitHub's compare API silently truncates at 300 files (this diff spans 698). The pin-drift check uses two recursive tree fetches and blob-exact comparison instead — no cap, and truncated tree responses are treated as API failure, never as "no drift".

Changes

  • package.json: devDependency pin f651433374e1cd (v0.1.1 tag commit; verified the only src/core change 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 in scripts/check-sync.mjs (fetched through the real sync pipeline).
  • scripts/check-core-pin.mjs + CI job: fails loudly when the pin's shipped src/core files differ from dspack-gen's latest release tag; *.test.ts excluded (documented escape for ahead-of-release pins); API failures warn and pass (report-only posture). Verified both ways: green on the tag pin, red naming src/core/generation-schema.ts on 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: repo aestheticfunction/ds-mcp, workflow release.yml).
  • README: the re-pin ritual now names the tag-pinned default posture and both CI checks.

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)

  1. Owner: register the npm trusted publisher (one-time).
  2. Tag v0.3.1 on main → release workflow publishes.
  3. Post-publish verification (PHASE-NEXT WS0 task 0.6): registry install, get-generation-context byte-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

…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>
Copilot AI review requested due to automatic review settings July 14, 2026 18:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 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-gen to the v0.1.1 tag commit and bump ds-mcp to 0.3.1 (with CHANGELOG shipped).
  • Add a golden-context test + tracked golden fixture synced via scripts/check-sync.mjs.
  • Add scripts/check-core-pin.mjs and 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.

Comment on lines +4 to +7
* 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
Comment on lines +59 to +63
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]}`,
);
Comment on lines +33 to +35
const response = await fetch(`${API}${path}`, {
headers: { accept: "application/vnd.github+json", "user-agent": "ds-mcp-check-core-pin" },
});
@ryandmonk
ryandmonk merged commit d7e6f30 into main Jul 14, 2026
3 checks passed
@ryandmonk

Copy link
Copy Markdown
Contributor Author

Post-publish verification (PHASE-NEXT WS0, task 0.6), run against the registry artifact:

  • npm view @aestheticfunction/ds-mcp version0.3.1 (integrity sha512-qvQGJusFLW1V...)
  • npm audit signatures8 packages have verified attestations (trusted publishing provenance active on the first tag-driven release)
  • Fresh npm install @aestheticfunction/ds-mcp@0.3.1 in a temp dir; get-generation-context({ intent: "destructive-action" }) against the shipped shadcn v0.4 contract, byte-compared to dspack-gen 0.1.1's fixtures/golden/context/shadcn.destructive-action.json:
registry ds-mcp 0.3.1 vs dspack-gen 0.1.1 golden — byte match: true

WS0 exit criteria are met. dspack-studio#13 (FM-11) is now unblocked: its take-home copy references ^0.3.1, which is live.

🤖 Generated with Claude Code

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