Skip to content

Vendor clean pgstencil with kysely as a Hosted peer, and fail on unmet peers - #742

Merged
nedtwigg merged 5 commits into
mainfrom
pgstencil-peers
Sep 22, 2026
Merged

nedtwigg merged 5 commits into
mainfrom
pgstencil-peers

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Depends on diffplug/pgstencil#8, and vendors that PR's commit 297edf6.

Vendor a clean pgstencil with kysely as a Hosted peer

  • pgstencil now shares kysely and hono with the app as peer dependencies instead of pinning its own copies. That split is what broke type-the-rhythm#355. hosted/package.json now declares kysely: ^0.29.5, so Renovate updates the single copy both sides use; hono was already declared.
  • The previous archives came from c14097c. This refresh adds pgstencil Setup our deployment pipeline #6 (expected auth rejections are no longer reported as server failures) and Add auto-update for the standalone app #7 (Microsoft signing keys without alg). Add auto-update for the standalone app #7 is the fix type-the-rhythm needed for Microsoft login, which Hosted also offers.
  • scripts/sync-pgstencil.mjs packs a committed pgstencil revision in a temporary clean worktree, so vendor/build.json now records dirty: false. verifyPackages in hosted/scripts/production.mjs rejected the old dirty build and accepts this one, so production releases are no longer blocked on this.
  • --working-tree replaces --packed for trying unfinished pgstencil changes; production refuses the dirty result.
  • Clean syncs of the same revision produce byte-identical archives (checked by syncing twice).
  • docs/specs/hosted.md gets a peer-dependency rule, and its word budget goes from 1050 to 1100 via --ratchet. hosted/README.md is updated to match.

Fail installs on unmet peer dependencies

strictPeerDependencies: true in pnpm-workspace.yaml. The workspace has no peer issues today (pnpm peers check). I checked that an out-of-range kysely (0.28.11) now fails the install. Deliberate widenings stay in peerDependencyRules.

Testing

On a fresh install with strict peers:

  • dormouse-hosted build and tests (18 passed)
  • verifyPackages
  • the dependency disclosure is unchanged
  • spec lint

🤖 Generated with Claude Code

nedtwigg and others added 2 commits September 21, 2026 16:59
pgstencil now shares kysely and hono with the application as peers
instead of pinning its own copies, so Hosted declares kysely and
Renovate updates the one copy both sides use. The refresh also brings
in pgstencil's Microsoft signing-key fix and quieter expected-rejection
diagnostics.

The sync script packs a committed revision in a temporary worktree, so
the recorded provenance is clean and production preflight accepts it;
--working-tree packs an unfinished checkout for local experiments.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A Renovate bump that leaves pgstencil's kysely or hono peer out of range
now goes red in its own PR instead of installing with a warning. The
workspace has no peer issues today; deliberate widenings stay in
peerDependencyRules.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 22, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9e95f83
Status: ✅  Deploy successful!
Preview URL: https://07cb089d.mouseterm.pages.dev
Branch Preview URL: https://pgstencil-peers.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feedback on work in progress, not a merge verdict — mark the PR ready when you want a full review.

The new peer-declaration rule is not enforced by anything. strictPeerDependencies: true catches an out-of-range peer, which is what the pnpm-workspace.yaml comment claims for it. It does not catch a peer the consumer stops declaring: pnpm auto-installs the missing peer into its own copy and the install goes green. So if a later edit drops kysely: ^0.29.5 from hosted/package.json, Hosted silently returns to the duplicate-copy state this PR exists to remove — Renovate stops seeing the version, and nothing goes red.

That also makes the section's closing line read wider than it is: Pinned by hosted/server/tests/artifacts.test.ts now sits under a rule that test does not check — it verifies the archive hashes and the two file: specifiers only. Its second test (both pinned specifiers name the recorded archives) already reads hosted/package.json's dependencies and the first already untars both archives, so asserting that every key of each archive's peerDependencies appears in dependencies would pin the rule, and would track pgstencil's peer list on its own rather than hardcoding kysely and hono.

How the pnpm behaviour was checked

Minimal workspace under pnpm 11.27.0 (the pinned packageManager): a file: tarball declaring peerDependencies: { kysely: "^0.29.5" }, strictPeerDependencies: true in pnpm-workspace.yaml, consumer declaring no kysely.

  • Consumer declares nothing: install exits 0, Packages: +2 — pnpm resolved the peer itself.
  • Consumer declares kysely@0.28.7: install fails with ERR_PNPM_PEER_DEP_ISSUESunmet peer kysely / Installed: 0.28.7 / Wanted: ^0.29.5.

One smaller point inline, on the new option parsing.

Comment thread scripts/sync-pgstencil.mjs Outdated
strictPeerDependencies only rejects an out-of-range peer; pnpm resolves
an undeclared one itself. The artifacts test now requires every peer of
each vendored archive in hosted/package.json. A mistyped sync flag used
to fall back to a clean sync of HEAD and overwrite the archives; it now
prints the usage instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feedback on work in progress, not a merge verdict — mark the PR ready when you want a full review.

Both earlier points are addressed: the test now derives each archive's peer list instead of hardcoding one, and a mistyped flag fails rather than quietly syncing HEAD.

--working-tree on a clean checkout records the same provenance as a worktree sync. dirty is workingTree && !!git("status", "--porcelain"), so a checkout with nothing uncommitted writes dirty: false against a real commit — and that is also the path that skips pnpm install --frozen-lockfile, since the install is gated on !workingTree. git status --porcelain says nothing about ignored paths, so the archives can be packed against whatever node_modules the developer happens to have and from build output the repo ignores, and verifyPackages takes them: assert.equal(manifest.dirty, false, ...) in hosted/scripts/production.mjs is its only check on how they were built. Recording which path produced them — a workingTree field asserted false beside dirty — is what makes the isolation the rewrite buys visible to the preflight.

The two pin checks still run after the install and the pack. They read hosted/package.json, the workspace overrides, and packages/*/package.json from the checkout, all available as soon as git worktree add returns, so a pgstencil version bump you forgot to mirror into hosted/package.json costs a full cold install in the temp worktree before it errors. Hoisting them above the pnpm install also closes the window where the first copyFileSync has already overwritten vendor/pgstencil-0.1.0.tgz and the second iteration throws, leaving build.json recording the old hash.

One inline suggestion on the spec line.

Comment thread docs/specs/hosted.md Outdated
… dirty

The version and override checks now read pgstencil's manifests from the
requested commit before the temporary install, so a forgotten bump fails
at once and cannot leave one archive replaced. A --working-tree build
depends on the local install and ignored build output even when git
status is clean, so it is always recorded dirty and production preflight
refuses it. The spec rule names every archive peer instead of listing
them, since the artifacts test derives the list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feedback on work in progress, not a merge verdict — mark the PR ready when you want a full review.

The earlier points are addressed: the pins are checked before the install and before any archive is overwritten, and --working-tree can no longer launder a clean-looking provenance.

dirty changed meaning, and docs/specs/hosted.md is the one place that still describes the old one. const dirty = workingTree records how the archives were built, not whether the source tree had uncommitted changes — a clean --working-tree checkout now gets dirty: true against a real commit. The source comment and hosted/README.md both carry the new meaning; the spec's only sentence on vendor/build.json still calls it "dirty state", so a reader who hits that dirty: true finds nothing in the spec saying it should be there. The same sentence is also where the production gate would belong — verifyPackages asserting dirty === false is the entire reason the field exists, and no spec states it today.

Suggestion inline; it fits the 1100-word budget as it stands (1068 now, 1078 after).

Comment thread docs/specs/hosted.md Outdated
…spec

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@nedtwigg
nedtwigg marked this pull request as ready for review September 22, 2026 23:11
@nedtwigg
nedtwigg merged commit 25221a0 into main Sep 22, 2026
12 checks passed
@nedtwigg
nedtwigg deleted the pgstencil-peers branch September 22, 2026 23:11
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