From 91283cec2bdd18c03152bb19b8c999d31e41aa5c Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Sat, 23 May 2026 14:15:31 -0300 Subject: [PATCH 1/2] fix(typecheck): one wrapper for SuperDoc public surface across CI lanes Extends check:public:superdoc (the wrapper script) to subsume the package-shape, snapshots, and classification-closure steps that ci-superdoc.yml, release-superdoc.yml, and release-stable.yml each ran separately. Adds two stages so all three lanes call a single command. scripts/check-public-contract.mjs: - Adds stages 4-6: package-shape-gate, snapshot --all --check, check-root-classification-closure. All three reuse the packed-and-installed fixture produced by stage 2 (typecheck-matrix), so ordering matters: matrix produces the install, the rest reuse it. - Updated header docstring to enumerate all six stages and explain why the post-install gates are grouped here. .github/workflows/: - ci-superdoc.yml: drop 3 duplicated steps (package-shape, snapshots, closure); the wrapper now covers them. Single step `pnpm check:public:superdoc --skip-build`. - release-superdoc.yml: drop 5 separate steps (matrix, audit, package-shape, snapshots, closure); replace with the same single wrapper call. - release-stable.yml: same replacement as release-superdoc.yml. Net: ~110 lines removed across the three workflows, ~30 added in the wrapper. A change to the validation chain (new stage, reorder, rename) now lands in one place and propagates to every lane automatically. package.json (alias inversion): - Canonical names now point at the real implementations: check:types -> tsc -b tsconfig.references.json check:public:superdoc -> node scripts/check-public-contract.mjs check:public:docapi -> the four docapi check commands generate:docapi -> tsx generate-contract-outputs.ts report:public:superdoc -> node scripts/report-public-contract.mjs - Legacy names delegate to canonical: type-check -> pnpm run check:types check:public-contract -> pnpm run check:public:superdoc docapi:check -> pnpm run check:public:docapi docapi:sync -> pnpm run generate:docapi docapi:sync:check -> generate:docapi && check:public:docapi report:public-contract -> pnpm run report:public:superdoc This makes the new names actually canonical (no extra alias hop in the hot path) and keeps --skip-build / other args forwarding cleanly through both name systems. Verified both `pnpm check:public:superdoc --skip-build` and `pnpm check:public-contract --skip-build` reach the SKIP branch in the wrapper. AGENTS.md + packages/superdoc/scripts/README.md: - Reflect that check:public:superdoc now runs all six stages. - Reflect that all three workflows call the wrapper directly. - Drop "tracked separately" caveat for the package-shape / snapshots / closure folding; that's now done. - Tag legacy aliases on each canonical command line so contributors who know the old name can find the new one. Verified: - pnpm check:public:superdoc (canonical) -> PASS 6 stages, 144.2s - pnpm check:public:superdoc --skip-build -> SKIP branch reached - pnpm check:public-contract --skip-build (legacy) -> same SKIP path - pnpm run check:types -> tsc clean - pnpm run type-check (legacy alias) -> tsc clean - pnpm run report:public:superdoc -> tier report (canonical) - pnpm run report:public-contract -> tier report (legacy alias) --- .github/workflows/ci-superdoc.yml | 50 +++++++------------------- .github/workflows/release-stable.yml | 27 ++++---------- .github/workflows/release-superdoc.yml | 33 ++++------------- AGENTS.md | 8 ++--- package.json | 22 ++++++------ packages/superdoc/scripts/README.md | 30 +++++++++------- scripts/check-public-contract.mjs | 49 ++++++++++++++++++++++--- 7 files changed, 102 insertions(+), 117 deletions(-) diff --git a/.github/workflows/ci-superdoc.yml b/.github/workflows/ci-superdoc.yml index aac05c9fd8..cb307198c8 100644 --- a/.github/workflows/ci-superdoc.yml +++ b/.github/workflows/ci-superdoc.yml @@ -120,46 +120,20 @@ jobs: # tree (those are tracked under SD-2863 follow-up tickets). run: pnpm --filter superdoc run check:jsdoc - - name: Public-contract check (matrix + supported-root strict audit) - # SD-673 Phase 1: collapse the previous two CI steps - # ('Consumer typecheck (matrix)' + 'Deep public-type audit') into - # the single wrapper command. Same coverage: - # - typecheck-matrix.mjs packs superdoc, installs the tarball - # into the consumer fixture, runs every scenario. - # - deep-type-audit.mjs --strict-supported-root reuses that - # install and gates on the supported-root any allowlist - # (SD-3213e). Broad inventory still printed for visibility. - # --skip-build because the Build step above already ran + - name: SuperDoc public interface check + # Single wrapper covering all SuperDoc public-surface gates: + # - typecheck-matrix.mjs (packs superdoc, runs every scenario) + # - deep-type-audit.mjs --strict-supported-root + # - package-shape-gate.mjs (publint + attw) + # - snapshot.mjs --all --check (super-editor / legacy / root) + # - check-root-classification-closure.mjs (SD-3212 A1b) + # All stages run from the same packed-and-installed fixture, so + # ordering matters: matrix produces the install; the rest reuse + # it. --skip-build because the Build step above already ran # `pnpm run build` (which includes build:superdoc). - # Local equivalent: `pnpm check:public-contract` (with the build + # Local equivalent: `pnpm check:public:superdoc` (with the build # stage included). - run: pnpm check:public-contract --skip-build - - - name: Package shape gates - # External package-shape linters (publint + attw) running against - # the packed tarball. Catches manifest issues that the in-repo - # consumer matrix does not see: condition ordering, masquerading - # ESM, missing CDN files, unpublished `source` paths. - run: node tests/consumer-typecheck/package-shape-gate.mjs - - - name: Public surface no-growth snapshots (SD-3176, SD-3212) - # Unified entry point for the three snapshot families: - # - super-editor-package: @superdoc/super-editor package.json#exports keys - # - legacy: resolved exports for superdoc/* legacy subpaths - # - root: 4-source inventory (types.import, types.require, import, - # require) for the superdoc root entry. Cross-source mismatches - # are reported in the companion .md but are not blockers on their - # own. - # Runs after the matrix step so the packed-and-installed fixture is - # available. See tests/consumer-typecheck/snapshots/README.md. - run: node tests/consumer-typecheck/snapshot.mjs --all --check - - - name: Root classification closure gate (SD-3212 PR A1b) - # Asserts the dependency-closure rule from the A1 classification: - # no supported-root or legacy-root exported root symbol may reference - # an internal-candidate root symbol in its public declared type. - # Catches the failure class behind Phase 4a's 31-failure dry-run. - run: node tests/consumer-typecheck/check-root-classification-closure.mjs + run: pnpm check:public:superdoc --skip-build unit-tests: needs: build diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index a7c2200a5d..f6e9addb36 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -114,26 +114,13 @@ jobs: # `latest` tag, so a regression that bypassed PR CI would otherwise # ship to every consumer pinned to `^1` or `latest`. Run identical # checks here so the stable lane cannot silently relax the gate. - - name: Consumer typecheck (matrix) - run: | - cd tests/consumer-typecheck - node typecheck-matrix.mjs - - - name: Deep public-type audit (supported-root strict, SD-3213e) - # Single invocation: broad inventory + supported-root strict gate. - # Same gate as PR CI. Catches releases that bypass PR CI. - run: node tests/consumer-typecheck/deep-type-audit.mjs --strict-supported-root - - - name: Package shape gates - run: node tests/consumer-typecheck/package-shape-gate.mjs - - - name: Public surface no-growth snapshots (SD-3176, SD-3212) - # Unified entry point for all three snapshot families - # (super-editor-package, legacy, root). Same gate as PR CI. - run: node tests/consumer-typecheck/snapshot.mjs --all --check - - - name: Root classification closure gate (SD-3212 PR A1b) - run: node tests/consumer-typecheck/check-root-classification-closure.mjs + - name: SuperDoc public interface check + # Wraps typecheck-matrix, deep-type-audit, package-shape-gate, + # snapshot --all --check, and check-root-classification-closure. + # Same coverage as PR CI; runs before stable release so any + # bypass path (manual republish, hotfix) still catches + # regressions. --skip-build because Build above already ran. + run: pnpm check:public:superdoc --skip-build - name: Release stable packages (orchestrator) id: stable_release diff --git a/.github/workflows/release-superdoc.yml b/.github/workflows/release-superdoc.yml index a16800bddd..0b2b922920 100644 --- a/.github/workflows/release-superdoc.yml +++ b/.github/workflows/release-superdoc.yml @@ -128,34 +128,15 @@ jobs: - name: Build packages run: pnpm run build - # Public-type contract gates: same gates as PR CI (ci-superdoc.yml). + # Public-type contract gate: same coverage as PR CI (ci-superdoc.yml). # Runs before publishing so a release cannot ship a regression that # bypassed PR CI (manual republish, hotfix branch, recovery flow). - - name: Consumer typecheck (matrix) - run: | - cd tests/consumer-typecheck - node typecheck-matrix.mjs - - - name: Deep public-type audit (supported-root strict, SD-3213e) - # Same gate as PR CI. One invocation prints the broad inventory - # AND runs the supported-root strict gate against the committed - # allowlist. Catches releases that bypass PR CI. - run: node tests/consumer-typecheck/deep-type-audit.mjs --strict-supported-root - - - name: Package shape gates - # External package-shape linters (publint + attw) running against - # the packed tarball. Same step as PR CI. - run: node tests/consumer-typecheck/package-shape-gate.mjs - - - name: Public surface no-growth snapshots (SD-3176, SD-3212) - # Same gate as PR CI. Catches releases that bypass PR CI. - # Runs the unified entry point for all three snapshot families - # (super-editor-package, legacy, root). - run: node tests/consumer-typecheck/snapshot.mjs --all --check - - - name: Root classification closure gate (SD-3212 PR A1b) - # Same gate as PR CI. Catches releases that bypass PR CI. - run: node tests/consumer-typecheck/check-root-classification-closure.mjs + - name: SuperDoc public interface check + # Wraps typecheck-matrix, deep-type-audit, package-shape-gate, + # snapshot --all --check, and check-root-classification-closure. + # --skip-build because the Build step above already ran + # `pnpm run build` (which includes build:superdoc). + run: pnpm check:public:superdoc --skip-build # PR preview: publish with pr- dist-tag - name: Publish PR preview diff --git a/AGENTS.md b/AGENTS.md index cc192d7481..aa75e3b98b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -71,10 +71,10 @@ Do not hand-edit `COMMAND_CATALOG`, `OPERATION_MEMBER_PATH_MAP`, `OPERATION_REFE - `pnpm build` - build all packages - `pnpm test` - unit tests - `pnpm dev` - dev server from `examples/` -- `pnpm check:types` - raw TS compile across all referenced projects (alias of `pnpm run type-check`). Does NOT run the public-interface chain. -- `pnpm check:public` - **canonical pre-merge command for typed public surfaces.** Validates both `superdoc` (vite build + postbuild chain + consumer typecheck matrix + deep-type audit) and Document API (contract parity + output staleness + examples + overview). ~5 min. Non-mutating. Combines `check:public:superdoc` + `check:public:docapi`. -- `pnpm check:public:superdoc` - SuperDoc public package surface only (alias of `check:public-contract`). -- `pnpm check:public:docapi` - Document API public surface only (alias of `docapi:check`). Requires generated artifacts to be current; if it fails on staleness, run `pnpm generate:docapi`. +- `pnpm check:types` - raw TS compile across all referenced projects (`tsc -b tsconfig.references.json`). Does NOT run the public-interface chain. Legacy alias: `pnpm run type-check`. +- `pnpm check:public` - **canonical pre-merge command for typed public surfaces.** Validates both `superdoc` (vite build + postbuild chain + consumer typecheck matrix + deep-type audit + package-shape + snapshots + classification closure) and Document API (contract parity + output staleness + examples + overview). ~5 min. Non-mutating. Combines `check:public:superdoc` + `check:public:docapi`. +- `pnpm check:public:superdoc` - SuperDoc public package surface only. Wraps six stages: build + matrix + deep-type audit + package-shape + snapshots + closure. Legacy alias: `pnpm run check:public-contract`. +- `pnpm check:public:docapi` - Document API public surface only. Requires generated artifacts to be current; if it fails on missing files, run `pnpm generate:docapi`. Legacy alias: `pnpm run docapi:check`. - `pnpm generate:docapi` - regenerate Document API outputs after editing the contract (alias of `docapi:sync`). Writes gitignored generated artifacts under the Document API package. Run before `check:public:docapi` if it fails on missing files. - `pnpm generate:all` - regenerate schemas, SDK clients, tool catalogs, reference docs. - `pnpm report:public:superdoc` - print public-contract tier metadata (supported / legacy / asset / deprecated). Read-only, not a gate. Source of truth: `packages/superdoc/scripts/type-surface.config.cjs`. diff --git a/package.json b/package.json index c875705e03..d206948dfe 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "test:behavior:headed": "pnpm --filter @superdoc-testing/behavior test:headed", "test:behavior:ui": "pnpm --filter @superdoc-testing/behavior test:ui", "test:behavior:html": "pnpm --filter @superdoc-testing/behavior test:html", - "type-check": "tsc -b tsconfig.references.json", + "type-check": "pnpm run check:types", "type-check:force": "tsc -b --force tsconfig.references.json", "rebuild:types": "pnpm --workspace-concurrency=1 run --filter=@superdoc/common --filter=@superdoc/word-layout --filter=@superdoc/contracts --filter=@superdoc/dom-contract --filter=@superdoc/layout-resolved --filter=@superdoc/geometry-utils --filter=@superdoc/style-engine --filter=@superdoc/pm-adapter --filter=@superdoc/measuring-dom --filter=@superdoc/layout-engine --filter=@superdoc/layout-bridge build && pnpm --filter=@superdoc/painter-dom build", "validate:commands": "node scripts/validate-command-types.mjs", @@ -71,23 +71,23 @@ "watch": "pnpm --prefix packages/superdoc run watch:es", "check:all": "pnpm run format && pnpm run lint:fix && pnpm --prefix packages/super-editor run types:build && pnpm run test", "check:examples-demos": "bun scripts/validate-examples-demos.ts", - "check:public-contract": "node scripts/check-public-contract.mjs", - "report:public-contract": "node scripts/report-public-contract.mjs", + "check:public-contract": "pnpm run check:public:superdoc", + "report:public-contract": "pnpm run report:public:superdoc", "local:publish": "pnpm --prefix packages/superdoc version prerelease --preid=local && pnpm --prefix packages/superdoc publish --registry http://localhost:4873", "update-preset-geometry": "ROOT=$(pwd) && cd ../superdoc-devtools/preset-geometry && pnpm run build && cp ./dist/index.js ./dist/index.js.map ./dist/index.d.ts \"$ROOT/packages/preset-geometry/\"", "manual-tag": "bash scripts/manual-tag.sh", "manual-clean-tag": "bash scripts/manual-clean-tag.sh", "generate:all": "node scripts/generate-all.mjs", "docapi:all": "pnpm run generate:all && pnpm exec tsc -b packages/document-api && pnpm --prefix apps/cli run build && pnpm --prefix packages/sdk run build:node", - "docapi:sync": "pnpm exec tsx packages/document-api/scripts/generate-contract-outputs.ts", - "docapi:check": "pnpm exec tsx packages/document-api/scripts/check-contract-parity.ts && pnpm exec tsx packages/document-api/scripts/check-contract-outputs.ts && pnpm exec tsx packages/document-api/scripts/check-examples.ts && pnpm exec tsx packages/document-api/scripts/check-overview-alignment.ts", - "docapi:sync:check": "pnpm run docapi:sync && pnpm run docapi:check", - "check:types": "pnpm run type-check", - "check:public:superdoc": "pnpm run check:public-contract", - "check:public:docapi": "pnpm run docapi:check", + "docapi:sync": "pnpm run generate:docapi", + "docapi:check": "pnpm run check:public:docapi", + "docapi:sync:check": "pnpm run generate:docapi && pnpm run check:public:docapi", + "check:types": "tsc -b tsconfig.references.json", + "check:public:superdoc": "node scripts/check-public-contract.mjs", + "check:public:docapi": "pnpm exec tsx packages/document-api/scripts/check-contract-parity.ts && pnpm exec tsx packages/document-api/scripts/check-contract-outputs.ts && pnpm exec tsx packages/document-api/scripts/check-examples.ts && pnpm exec tsx packages/document-api/scripts/check-overview-alignment.ts", "check:public": "pnpm run check:public:superdoc && pnpm run check:public:docapi", - "generate:docapi": "pnpm run docapi:sync", - "report:public:superdoc": "pnpm run report:public-contract", + "generate:docapi": "pnpm exec tsx packages/document-api/scripts/generate-contract-outputs.ts", + "report:public:superdoc": "node scripts/report-public-contract.mjs", "test:cli": "pnpm --prefix apps/cli run test", "cli:prepare": "pnpm run test:cli && pnpm --prefix apps/cli run build:prepublish", "cli:publish:raw": "pnpm run cli:prepare && pnpm --prefix apps/cli run publish:platforms", diff --git a/packages/superdoc/scripts/README.md b/packages/superdoc/scripts/README.md index 08354274f0..097d0e0bd6 100644 --- a/packages/superdoc/scripts/README.md +++ b/packages/superdoc/scripts/README.md @@ -121,11 +121,12 @@ what an actual consumer would see — not the workspace source. | `package-shape-gate.mjs` | External package-shape linters (publint + attw) against the packed tarball. | Catches condition ordering, masquerading exports, missing field declarations. | | `check-root-classification-closure.mjs` | Asserts no `supported-root` or `legacy-root` export references an `internal-candidate` symbol in its public declared type. | Closure rule from SD-3212. | -`check:public:superdoc` runs `typecheck-matrix` and `deep-type-audit` -directly. `package-shape-gate`, `snapshot --all --check`, and -`check-root-classification-closure` currently run as separate CI steps — -folding them into `check:public:superdoc` is tracked as a follow-up so -release workflows can call one command without losing coverage. +`check:public:superdoc` runs all six of these in order: `typecheck-matrix` +packs and installs the SuperDoc tarball into the fixture, then the +remaining five gates reuse that install. CI (`ci-superdoc.yml`) and +release workflows (`release-superdoc.yml`, `release-stable.yml`) call +`pnpm check:public:superdoc --skip-build` directly — no duplicated step +lists. --- @@ -178,14 +179,17 @@ packages/document-api/src/contract/operation-definitions.ts ## CI vs local -- **`ci-superdoc.yml`** runs `pnpm check:public-contract --skip-build` after - its own Build step. This is the single command for the SuperDoc public - surface in CI. -- **`release-superdoc.yml`** currently runs the consumer-typecheck matrix, - deep-type audit, package-shape gate, snapshot check, and classification - closure as separate steps. Migrating to `check:public:superdoc` once that - command covers all the gates is tracked separately. +All three SuperDoc lanes call the same wrapper: + +- **`ci-superdoc.yml`** (PR CI) — `pnpm check:public:superdoc --skip-build` after the Build step. +- **`release-superdoc.yml`** (preview/dev release) — same. +- **`release-stable.yml`** (stable release) — same. + +The wrapper enforces every SuperDoc public-surface gate in one place. +A change to the validation chain (adding a stage, reordering, renaming) +lands in `scripts/check-public-contract.mjs` and propagates to all +three lanes automatically. Local pre-commit: just run `pnpm check:public`. If anything fails, the failure message tells you which script and (for `check:public:docapi`) -which command to run to regenerate stale artifacts. +which command to run to regenerate missing or stale artifacts. diff --git a/scripts/check-public-contract.mjs b/scripts/check-public-contract.mjs index 3477f50169..4963c422df 100755 --- a/scripts/check-public-contract.mjs +++ b/scripts/check-public-contract.mjs @@ -17,18 +17,30 @@ * 3. deep-type-audit - strict gate on the supported-root public * surface (must be 0 findings). Reuses the * install that stage 2 produced (no `--pack`). + * 4. package-shape - publint + attw against the packed manifest + * (reuses the install from stage 2). + * 5. snapshots - super-editor / legacy / root no-growth + * snapshots (reuses the install). + * 6. closure - root-classification closure gate: + * no supported-root/legacy-root export + * references an internal-candidate type. * - * Matrix runs BEFORE audit on purpose: matrix packs + installs the - * tarball once, and the audit then reuses that install. Without this - * order the audit would `--pack` separately and double the work. + * Matrix runs BEFORE the post-install gates on purpose: matrix packs + + * installs the tarball once, and stages 3-6 reuse that install. + * Without this order each downstream stage would `--pack` separately + * and multiply the work. * * Local usage: - * pnpm check:public-contract + * pnpm check:public (umbrella, runs SuperDoc + Document API) + * pnpm check:public:superdoc (SuperDoc only, this script) * * CI usage (Build step already ran): - * pnpm check:public-contract --skip-build + * pnpm check:public:superdoc --skip-build * * SD-3256 Phase 1 (initial wrapper) / SD-673 Phase 1 (CI wiring). + * Extended in the typecheck-wrapper consolidation PR to subsume the + * package-shape / snapshots / closure steps that release-superdoc.yml, + * release-stable.yml, and ci-superdoc.yml previously ran separately. */ import { spawnSync } from 'node:child_process'; @@ -70,6 +82,33 @@ const stages = [ 'Strict gate on the supported-root public surface (must be 0 findings). ' + 'Reuses the install produced by typecheck-matrix.', }, + { + name: 'package-shape-gate', + cwd: resolve(REPO_ROOT, 'tests/consumer-typecheck'), + cmd: 'node', + args: ['package-shape-gate.mjs'], + blurb: + 'External npm-package linters (publint + attw) against the packed manifest. ' + + 'Reuses the install produced by typecheck-matrix.', + }, + { + name: 'snapshot --all --check', + cwd: resolve(REPO_ROOT, 'tests/consumer-typecheck'), + cmd: 'node', + args: ['snapshot.mjs', '--all', '--check'], + blurb: + 'No-growth snapshots for super-editor / legacy / root export inventories. ' + + 'Run with `node snapshot.mjs --family --write` to regenerate intentionally.', + }, + { + name: 'check-root-classification-closure', + cwd: resolve(REPO_ROOT, 'tests/consumer-typecheck'), + cmd: 'node', + args: ['check-root-classification-closure.mjs'], + blurb: + 'Closure gate: no supported-root or legacy-root export references an ' + + 'internal-candidate type in its public declared shape (SD-3212 A1b).', + }, ]; const HR = '='.repeat(72); From f1196526df8418ca1c91089cb528c2aecbfce70d Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Sat, 23 May 2026 19:18:42 -0300 Subject: [PATCH 2/2] docs(typecheck): clarify which downstream stages reuse what (typecheck-wrapper PR-2) Review-feedback wording correction. The previous text said "stages 3-6 reuse the install produced by typecheck-matrix" but that conflated two distinct inputs: - deep-type-audit, snapshot, and check-root-classification-closure read from the consumer fixture's node_modules/superdoc/ (installed via the tarball). - package-shape-gate reads the tarball directly (packages/superdoc/superdoc.tgz), not the installed fixture. Updated the script's header docstring and the package-shape-gate stage blurb to call out the distinction. Updated the matching paragraph in packages/superdoc/scripts/README.md. No behavior change. --- packages/superdoc/scripts/README.md | 10 +++++++--- scripts/check-public-contract.mjs | 12 +++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/superdoc/scripts/README.md b/packages/superdoc/scripts/README.md index 097d0e0bd6..95407ad59c 100644 --- a/packages/superdoc/scripts/README.md +++ b/packages/superdoc/scripts/README.md @@ -121,9 +121,13 @@ what an actual consumer would see — not the workspace source. | `package-shape-gate.mjs` | External package-shape linters (publint + attw) against the packed tarball. | Catches condition ordering, masquerading exports, missing field declarations. | | `check-root-classification-closure.mjs` | Asserts no `supported-root` or `legacy-root` export references an `internal-candidate` symbol in its public declared type. | Closure rule from SD-3212. | -`check:public:superdoc` runs all six of these in order: `typecheck-matrix` -packs and installs the SuperDoc tarball into the fixture, then the -remaining five gates reuse that install. CI (`ci-superdoc.yml`) and +`check:public:superdoc` runs all six in order. `typecheck-matrix` packs +`superdoc.tgz` and installs it into the consumer fixture. The rest +reuse what matrix produced: `deep-type-audit`, `snapshot --all +--check`, and `check-root-classification-closure` read from the +installed fixture in `node_modules/superdoc/`; `package-shape-gate` +runs `publint` / `attw` against the packed tarball at +`packages/superdoc/superdoc.tgz` directly. CI (`ci-superdoc.yml`) and release workflows (`release-superdoc.yml`, `release-stable.yml`) call `pnpm check:public:superdoc --skip-build` directly — no duplicated step lists. diff --git a/scripts/check-public-contract.mjs b/scripts/check-public-contract.mjs index 4963c422df..bba8a5194e 100755 --- a/scripts/check-public-contract.mjs +++ b/scripts/check-public-contract.mjs @@ -25,10 +25,12 @@ * no supported-root/legacy-root export * references an internal-candidate type. * - * Matrix runs BEFORE the post-install gates on purpose: matrix packs + - * installs the tarball once, and stages 3-6 reuse that install. - * Without this order each downstream stage would `--pack` separately - * and multiply the work. + * Matrix runs BEFORE stages 3-6 on purpose: it packs `superdoc.tgz` + * and installs the tarball into the consumer fixture once. Stages 3, + * 5, and 6 (deep-type-audit, snapshots, closure) reuse the installed + * fixture; stage 4 (package-shape-gate) reuses the packed tarball + * directly. Without this ordering each downstream stage would + * `--pack` separately and multiply the work. * * Local usage: * pnpm check:public (umbrella, runs SuperDoc + Document API) @@ -89,7 +91,7 @@ const stages = [ args: ['package-shape-gate.mjs'], blurb: 'External npm-package linters (publint + attw) against the packed manifest. ' + - 'Reuses the install produced by typecheck-matrix.', + 'Reuses the tarball produced by typecheck-matrix (not the installed fixture).', }, { name: 'snapshot --all --check',