Skip to content

Commit 82fcd0f

Browse files
hotlongclaude
andcommitted
test(scripts): add the consumer-resolution regression control (#16186)
Pinning the version fixes today's break and leaves the repository exactly as blind as it was: `pnpm-lock.yaml` held `@better-auth/core@1.7.2`, so every job here imported the version that still had `createLocalAccountIssuer` while every consumer resolved `^1.7.2` to 1.7.3 and could not load the plugin at all. `scripts/check-vendor-export-contract.mjs` closes that class. For every governed vendor a publishable package statically imports runtime values from, it asserts the declared range is an EXACT version, that the installed copy IS that version, and that importing each specifier really yields every symbol our shipped source takes from it — so "what CI imported" and "what a consumer resolves" are the same string. `--resolve` measures the same property instead of proving it: it enumerates every registry version the DECLARED range admits, installs each outside this workspace, and fails if any is missing a symbol we import. Wired into validate-deps.yml, which already has the network and runs daily; the offline leg runs in the lint farm on every PR. `check-override-consistency.mjs` structurally cannot cover this — it asks whether the override target is reachable from the declared range, and `^1.7.2` agreed with `^1.7.2` all the way onto the broken version. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 3409241 commit 82fcd0f

4 files changed

Lines changed: 622 additions & 0 deletions

File tree

.github/workflows/lint.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,24 @@ jobs:
26152615
- name: Auth mount-vs-ledger guard
26162616
run: pnpm check:auth-mount-ledger
26172617

2618+
# Vendor export contract (#16186). `@better-auth/core@1.7.3` deleted
2619+
# `createLocalAccountIssuer` in a PATCH; plugin-auth imports it statically
2620+
# through a caret range, so published 17.1.0-17.3.0 could not load at all
2621+
# on a fresh install -- while every job here stayed green, because
2622+
# pnpm-lock.yaml held 1.7.2. The lockfile protected the producer from the
2623+
# defect it was shipping. This gate asserts that a governed vendor's
2624+
# DECLARED range is exact, that the installed version IS that version, and
2625+
# that importing it really yields every symbol our shipped source takes
2626+
# from it -- so "what CI imported" and "what a consumer resolves" are the
2627+
# same string. Cheap and offline: it imports what `pnpm install` already
2628+
# put on disk. The network half (`--resolve`, which enumerates every
2629+
# registry version the range admits) runs in validate-deps.yml, which
2630+
# already installs from the registry. No `paths:` filter: a manifest edit,
2631+
# a lockfile refresh and a new vendor import can each move it. Runs its
2632+
# own --self-test first.
2633+
- name: Vendor export contract
2634+
run: pnpm check:vendor-export-contract
2635+
26182636
# Optional-`error` sink contract (#9754, wired by #10608). A sink TYPE that
26192637
# declares `error` as OPTIONAL must also declare `warn` as NON-optional, so
26202638
# every value of that type has somewhere to put a durability report —

.github/workflows/validate-deps.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
- 'pnpm-workspace.yaml'
1010
- 'scripts/check-changeset-fixed.mjs'
1111
- 'scripts/check-override-consistency.mjs'
12+
# The consumer-resolution half of the same question (#16186) — an edit to
13+
# the gate must be exercised on the PR that makes it.
14+
- 'scripts/check-vendor-export-contract.mjs'
1215
# The OSV exemption ledger and its check: a PR that touches either must
1316
# run this workflow, or an exemption could be added without the gate
1417
# that governs it ever running on the PR that adds it.
@@ -83,6 +86,29 @@ jobs:
8386
- name: Verify overrides are reflected in published manifests
8487
run: pnpm check:override-consistency
8588

89+
# The half check-override-consistency structurally cannot cover (#16186).
90+
# It asks whether the override TARGET is reachable from the declared
91+
# range; `^1.7.2` and `^1.7.2` agreed perfectly while both floated onto
92+
# `@better-auth/core@1.7.3`, a PATCH that deleted the export plugin-auth
93+
# imports statically. Three published releases could not load on a fresh
94+
# install and nothing here went red, because pnpm-lock.yaml held 1.7.2.
95+
#
96+
# `--resolve` deliberately ignores the lockfile: for every version the
97+
# DECLARED range admits on the registry -- the way a downstream project
98+
# resolves -- it installs that version outside this workspace and checks
99+
# the export surface. It fails if ANY admitted version is missing a symbol
100+
# we import. With the ranges pinned exact that is one small install per
101+
# vendor; under a caret it is one per published version, which is the cost
102+
# of the risk being taken.
103+
#
104+
# It lives HERE rather than in the lint farm because it needs the network,
105+
# which this job already has, and because the daily schedule is what turns
106+
# "a vendor published something today" into a red in this repo instead of
107+
# in a customer's install. An unreachable registry exits 3
108+
# (PREREQUISITE NOT MET), never a green.
109+
- name: Verify the declared ranges cannot resolve past our import surface
110+
run: pnpm check:vendor-export-contract-resolve
111+
86112
# Fail the workflow if known vulnerabilities are found — enforces
87113
# security compliance before merging.
88114
#

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@
125125
"check:adr-0087-registration": "node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-adr-0087-registration.mjs",
126126
"check:changeset-gate-self-tests": "node scripts/check-empty-changeset.mjs --self-test && node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-changeset-no-major.mjs --self-test",
127127
"check:override-consistency": "node scripts/check-override-consistency.mjs --self-test && node scripts/check-override-consistency.mjs",
128+
"check:vendor-export-contract": "node scripts/check-vendor-export-contract.mjs --self-test && node scripts/check-vendor-export-contract.mjs",
129+
"check:vendor-export-contract-resolve": "node scripts/check-vendor-export-contract.mjs --self-test && node scripts/check-vendor-export-contract.mjs --resolve",
128130
"check:release-notes": "node scripts/check-release-notes.mjs",
129131
"check:release-page-status": "node scripts/check-release-page-status.mjs --self-test && node scripts/check-release-page-status.mjs",
130132
"check:release-body": "node scripts/release-github-releases.mjs --self-test",

0 commit comments

Comments
 (0)