From c41a088b31fba32118d5fa2d36840cb06094ad8f Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 03:19:17 +0000 Subject: [PATCH] docs(tests): correct four stale claims about what check:cross-package-test-inputs recognises MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gate resolves four directory-naming seed spellings plus the walked-file form, not "exactly two". `import.meta.dirname` and `dirname(import.meta.filename)` arrived with #9763 and the walked `import.meta.url` seed with #8995; both extensions updated RECOGNISED_PATH_SPELLINGS, which the gate prints, and neither swept for the count restated in prose elsewhere. Corrected, pointing at RECOGNISED_PATH_SPELLINGS as the single source instead of restating a number that drifts: - managed-extension-fields.test.ts: the seed count, plus two more stale claims measured on this tree — it is no longer the ONLY escaping read the gate sees in plugin-auth (#10161 made rate-limit-storage-isolation.test.ts visible), and that file no longer walks up from process.cwd(). The note also promised a stale-declaration failure that no longer fires: reseeding this file from process.cwd() now leaves the gate GREEN, with packages/**/*.object.ts declared and held by nothing. - managed-api-method-affordance-sweep.test.ts: the same seed count. Its stale-declaration consequence IS still real and is now cited from the measurement (that file is platform-objects' only escaping test; the ablation exits 1 naming the package). - check-type-check-coverage.mjs: the same claim in a TEST_DEBT note, the worst-placed instance since an author reads it while choosing a seed. - serve-multi-node-cap-advisory.pin.test.ts (not named in the card): stale in the opposite direction — it claimed the gate cannot follow a new URL() seed or a resolve() nested into the read. It follows both. The instruction to keep the whole path in one literal stands, for the reason that is actually true: only the flat literal collector needs that spelling. Comments and one note string only — no test code, no type surface. The gate's own repoRelativeLiterals roster for all three test files is unchanged from origin/main, so no declaration and no turbo.json input moves. Part of #10163 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt --- .../serve-multi-node-cap-advisory.pin.test.ts | 27 ++++++++++---- ...anaged-api-method-affordance-sweep.test.ts | 25 ++++++++----- .../src/managed-extension-fields.test.ts | 36 ++++++++++++------- scripts/check-type-check-coverage.mjs | 5 ++- 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts b/packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts index 61daf34534..29b14ab6a2 100644 --- a/packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts +++ b/packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts @@ -49,12 +49,27 @@ const SERVE_SOURCE = readFileSync(resolve(HERE, 'serve.ts'), 'utf8'); * reading `src` also means the pin does not depend on anything being built. * * ⚠️ Addressed as a repo-relative literal off an escaping `REPO_ROOT` binding - * on purpose — that is the shape the repo's `check:cross-package-test-inputs` - * gate can follow. (Its script is named without a repo-relative path here: that - * gate collects path literals out of a test's source, comments included, and - * would then require a glob for a file this test never reads.) Spellings it cannot follow (a `new URL('…', import.meta.url)` - * seed, or a `resolve()` nested straight into the `readFileSync` call) read - * identically at runtime but produce no binding and therefore no flag, which + * on purpose — that is the shape BOTH halves of the repo's + * `check:cross-package-test-inputs` gate see. (Its script is named without a + * repo-relative path here: that gate collects path literals out of a test's + * source, comments included, and would then require a glob for a file this test + * never reads.) + * + * This note used to say the gate could not follow a `new URL('…', + * import.meta.url)` seed or a `resolve()` nested straight into the + * `readFileSync` call. It follows both, and has since #9763 — both are on its + * published `RECOGNISED_PATH_SPELLINGS` list, printed in its failure text, and + * each is pinned by a `--self-test` case; measured on ceb33a9f12, both produce + * the escape flag. What they miss is the FLAT literal collector, which sees a + * path only when the whole repo-relative string sits inside ONE quoted literal + * starting at a top-level directory: written ascent-relative, this read's name + * would reach the radius roster only through the resolver's reconstruction, + * where the spelling below reaches it through both. So keep the whole path in + * one literal — but for that reason, not because the alternatives are invisible. + * + * The spellings that genuinely produce no flag are the ones the detector cannot + * resolve at all: a template-literal path, a `findUp` walk from `process.cwd()`, + * segments arriving out of a variable or an array. Reaching for one of those * would leave this read **undeclared**: `@objectstack/cli` would then be absent * from `turbo ls --affected` for a cluster-only change and its `test` cache * would not hash this file, so the pin below would sit green through exactly diff --git a/packages/platform-objects/src/managed-api-method-affordance-sweep.test.ts b/packages/platform-objects/src/managed-api-method-affordance-sweep.test.ts index 71e393c8a7..e5257dd7df 100644 --- a/packages/platform-objects/src/managed-api-method-affordance-sweep.test.ts +++ b/packages/platform-objects/src/managed-api-method-affordance-sweep.test.ts @@ -101,14 +101,23 @@ import { MANAGED_API_METHOD_UNAFFORDABLE, validateManagedApiMethods } from '@obj * in front of tsc, `import.meta` becomes an error in a ledger that may only * shrink. `__dirname` type-checks under the package's own config and is * defined at runtime by vitest's transform (verified, not assumed). - * - `check:cross-package-test-inputs` recognises exactly two seeds — - * `dirname(fileURLToPath(import.meta.url))` and `__dirname` — when it detects - * statically that a test escapes its package. Deriving the root any other way - * (walking up to `pnpm-workspace.yaml`, resolving from `process.cwd()`) makes - * this file's real radius INVISIBLE to that gate, which then reports the - * declaration below as stale and asks for its removal. Losing it would put - * the sweep back in #7802's blind spot: turbo would cache a green for a diff - * that changed another package's object file. Measured both ways. + * - `check:cross-package-test-inputs` detects an escaping read STATICALLY, by + * resolving the seed expression, and `__dirname` is one of the spellings it + * resolves. Which spellings those are is published rather than restated + * here: `RECOGNISED_PATH_SPELLINGS` in the detector, printed verbatim in its + * failure text and mirrored in AGENTS.md. Read it there — the set has been + * widened twice (#8995, #9763) since this note was first written, and a + * count copied into a comment goes stale silently while the published list + * cannot. Deriving the root a way the detector does NOT resolve (walking up + * to `pnpm-workspace.yaml`, resolving from `process.cwd()`) makes this + * file's real radius INVISIBLE to that gate, which then reports the + * declaration below as stale and asks for its removal — this file is + * platform-objects' only escaping test, so hiding it empties the package. + * Measured on ceb33a9f12 by reseeding from `process.cwd()`: the gate exits 1 + * with "@objectstack/platform-objects declares a cross-package input radius, + * but no test in it reads outside the package any more". Acting on that and + * deleting the entry would put the sweep back in #7802's blind spot: turbo + * would cache a green for a diff that changed another package's object file. */ const HERE = __dirname; /** …/packages/platform-objects/src → repo root */ diff --git a/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts b/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts index 82224cbf70..8560b2abe2 100644 --- a/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts +++ b/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts @@ -305,19 +305,29 @@ const COVERED_OBJECTS: readonly string[] = [ * only shrink. * `__dirname` type-checks under the package's own config and is defined at * runtime by vitest's transform (verified, not assumed). - * - `check:cross-package-test-inputs` recognises exactly two seeds — - * `dirname(fileURLToPath(import.meta.url))` and `__dirname` — when it - * detects statically that a test escapes its package. This file's walk of - * `PACKAGES_DIR` below is the ONLY escaping read the gate can see in - * plugin-auth, so it is what holds the package's declared radius - * (`packages/**\/*.object.ts`) and the matching `turbo.json` inputs. - * Deriving the root any other way — the `findUp` walk from `process.cwd()` - * that `rate-limit-storage-isolation.test.ts` and - * `member-role-canonical.test.ts` use — makes this radius INVISIBLE to that - * gate, which then reports the declaration as stale and asks for its - * removal. Losing it would put this sweep back in #7802's blind spot: - * turbo would replay a cached green for a diff that changed another - * package's object file. Measured both ways. + * - `check:cross-package-test-inputs` detects an escaping read STATICALLY, by + * resolving the seed expression, and `__dirname` is one of the spellings it + * resolves. Which spellings those are is published rather than restated + * here: `RECOGNISED_PATH_SPELLINGS` in the detector, printed in its failure + * text and mirrored in AGENTS.md. Read it there — the set has been widened + * twice (#8995, #9763) since this note was first written, and a count + * copied into a comment goes stale silently while the published list cannot. + * This file's walk of `PACKAGES_DIR` below is what holds the + * `packages/**\/*.object.ts` half of plugin-auth's declared radius and the + * matching `turbo.json` inputs: it is the only escaping read in this package + * that reaches an object file anywhere in the tree. Deriving the root any + * other way — the `findUp` walk from `process.cwd()` that + * `member-role-canonical.test.ts` uses — makes this radius INVISIBLE to + * that gate, and note what that does NOT do any more: since #10161 gave + * plugin-auth a second visible escaping test + * (`rate-limit-storage-isolation.test.ts`, whose roster is the two consumer + * directories, not this glob), the package no longer goes stale-empty, so + * the gate stays GREEN and this glob is simply held by nothing. Measured on + * ceb33a9f12 by reseeding this file from `process.cwd()`: `--list-escapes` + * dropped this file and `--verify` still exited 0. Losing the seed would put + * this sweep back in #7802's blind spot with no gate reporting it: turbo + * would replay a cached green for a diff that changed another package's + * object file. */ const HERE = __dirname; /** …/packages/plugins/plugin-auth/src → repo root */ diff --git a/scripts/check-type-check-coverage.mjs b/scripts/check-type-check-coverage.mjs index dba5b6ce2e..e273e322bc 100644 --- a/scripts/check-type-check-coverage.mjs +++ b/scripts/check-type-check-coverage.mjs @@ -752,7 +752,10 @@ const TEST_DEBT = { + '110 -> 109 here (#9694): src/managed-extension-fields.test.ts held the package\'s only ' + 'TS1470 -- an `import.meta.url` seed in a package that is CJS-typed and therefore forbids ' + 'the meta-property under module: NodeNext -- and now seeds from `__dirname`, which ' - + 'type-checks here AND is one of the two seeds check:cross-package-test-inputs recognises, so ' + + 'type-checks here AND is a seed spelling check:cross-package-test-inputs resolves -- the ' + + 'current set is that gate\'s published RECOGNISED_PATH_SPELLINGS, printed verbatim in its ' + + 'failure text, and is deliberately not restated as a count here because a count drifts ' + + 'silently (it has been widened twice, #8995 and #9763) -- so ' + 'that file\'s repo-wide *.object.ts walk stays visible to the gate holding plugin-auth\'s ' + 'declared input radius. It contributes nothing to this pile any more.', },