From f30da6d0e6fc49edc6ef2fe30059e98c1e3cc4bf Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 09:52:47 +0000 Subject: [PATCH] fix(scripts): move check-ci-filter-parity's fixture builders inside selfTest() The fixture builder, its condition constant and its declaration-table helper sat at module scope while being used only by selfTest(). dispatch-gates.mjs blanks self-test BODIES before scanning a gate's module body for the path literals it reads, so a module-scope fixture helper escapes that blanking and its fixture globs are read as the gate's declared population. The two subtree globs the core/crosspkg defaults spell put this gate in the MATCHED column for 5326 tracked files it never opens. Its real population is .github/workflows/ci.yml and its own source. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx --- scripts/check-ci-filter-parity.mjs | 75 +++++++++++++++++++----------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/scripts/check-ci-filter-parity.mjs b/scripts/check-ci-filter-parity.mjs index 900c1f8b69..521d002c96 100644 --- a/scripts/check-ci-filter-parity.mjs +++ b/scripts/check-ci-filter-parity.mjs @@ -382,35 +382,56 @@ function list(root = REPO_ROOT, table = CROSS_PACKAGE_TEST_INPUTS) { // is a different file and must be named), and a declaration under a root that // appears nowhere at all. -/** A ci.yml source carrying the two scheduling lists, in the real shape. */ -const REAL_TEST_IF = - "${{ !cancelled() && (needs.filter.outputs.core != 'false' || needs.filter.outputs.crosspkg != 'false') }}"; - -function fixtureWorkflow({ core, crosspkg, condition = REAL_TEST_IF } = {}) { - const list = (entries) => entries.map((e) => ` - '${e}'`).join('\n'); - return [ - 'name: CI', - 'jobs:', - ' filter:', - ' steps:', - ' - uses: dorny/paths-filter@v4', - ' id: changes', - ' with:', - ' filters: |', - ' core:', - list(core ?? ['packages/**', '.github/workflows/ci.yml']), - ` ${REMEDY_FILTER}:`, - list(crosspkg ?? ['scripts/**']), - ' test:', - ` if: ${JSON.stringify(condition)}`, - ' steps:', - ' - run: echo test', - ].join('\n'); -} - -const table = (globs) => ({ '@objectstack/probe': { globs } }); +// ⛔ The fixture builders below live INSIDE `selfTest()` and must stay there +// (#10841). `scripts/pm/dispatch-gates.mjs` scans a gate's MODULE BODY for the +// path literals it reads -- blanking comments and self-test BODIES first -- and +// prints the gate as a local gate for every card those literals cover. A fixture +// helper hoisted to module scope escapes that blanking, and its fixture globs are +// then read as this gate's declared population. +// +// Measured on `3637731e2` before the move: this gate's hint set was +// `.github/workflows/ci.yml` (real) plus the two subtree globs the `core`/ +// `crosspkg` defaults spell and the fixture table's package name (all three +// fabricated), and the pair census put it in the MATCHED column for 5328 of 6511 +// tracked files. Its real population is ci.yml and its own source: 2. A +// fabricated lead is pasted into a dispatch prompt and cannot be told apart from +// an earned one, so the cost was paid by every card under two of the largest +// directories in the tree. +// +// A fixture that must be module-scope for some other reason can still be spelled +// safely -- assemble it from unslashed halves the way `DEFAULT_BASE_REF` does in +// dispatch-gates.mjs, so only the joined value is pathy and it exists at runtime +// alone. export async function selfTest() { + /** A ci.yml source carrying the two scheduling lists, in the real shape. */ + const REAL_TEST_IF = + "${{ !cancelled() && (needs.filter.outputs.core != 'false' || needs.filter.outputs.crosspkg != 'false') }}"; + + function fixtureWorkflow({ core, crosspkg, condition = REAL_TEST_IF } = {}) { + const list = (entries) => entries.map((e) => ` - '${e}'`).join('\n'); + return [ + 'name: CI', + 'jobs:', + ' filter:', + ' steps:', + ' - uses: dorny/paths-filter@v4', + ' id: changes', + ' with:', + ' filters: |', + ' core:', + list(core ?? ['packages/**', '.github/workflows/ci.yml']), + ` ${REMEDY_FILTER}:`, + list(crosspkg ?? ['scripts/**']), + ' test:', + ` if: ${JSON.stringify(condition)}`, + ' steps:', + ' - run: echo test', + ].join('\n'); + } + + const table = (globs) => ({ '@objectstack/probe': { globs } }); + const failures = []; let checked = 0; const assert = (cond, label) => {