From 84f6eb5b02e63200b2c70153e10e0a92e1062039 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 11:24:36 +0000 Subject: [PATCH] docs(scripts): point five gate scripts at lint.yml's idiom note instead of restating the #9465 fence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven sites in `scripts/**` stated the @changesets/cli v3 lane's fence as covering root `package.json` as a FILE (or, in the ratchet, root dependencies as a CLASS). The lane's own body scopes it to one dependency range and one script key, so those readings are false — #10894 corrected the same reading at nineteen sites inside `.github/workflows/lint.yml` and put the reasons in one place, the `GATE INVOCATION IDIOM` note. This is the half of that repair that `lint.yml` could not reach. Each site now points at that note rather than restating the scope, because restating it is the propagation mechanism the card measured: three of these docblocks were identically worded because their authors copied a neighbour's header, and a seventh careful restatement would be a seventh copy source. No wiring changes. The three self-test wiring assertions keep their predicate byte-identical (`lint.includes('node \n')`); only the message string moved, and all three self-tests report the same assertion counts before and after (39 / 77 / 45). `scripts/check-step-collectors.mjs` is deliberately untouched — it already states the scope narrowly and is the model. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6 --- scripts/check-aggregator-roster.mjs | 2 +- scripts/check-ci-filter-parity.mjs | 14 ++++++++------ scripts/check-doc-frontmatter.mjs | 16 +++++++++------- scripts/check-platform-checklist.mjs | 19 +++++++++++-------- scripts/check-skills-token-ratchet.mjs | 7 +++++-- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/scripts/check-aggregator-roster.mjs b/scripts/check-aggregator-roster.mjs index d034550585..1bd3a16dea 100644 --- a/scripts/check-aggregator-roster.mjs +++ b/scripts/check-aggregator-roster.mjs @@ -580,7 +580,7 @@ async function selfTest() { { const lint = sources['lint.yml']; const self = 'scripts/check-aggregator-roster.mjs'; - assert(lint.includes(`node ${self}\n`), `wiring: lint.yml invokes ${self} directly (no root package.json alias -- #9465 fence)`); + assert(lint.includes(`node ${self}\n`), `wiring: lint.yml invokes ${self} directly (lint.yml's GATE INVOCATION IDIOM note, not a package.json fence)`); assert(lint.includes(`node ${self} --self-test`), 'wiring: lint.yml runs the --self-test half too'); } diff --git a/scripts/check-ci-filter-parity.mjs b/scripts/check-ci-filter-parity.mjs index 75c979a5e8..89a9fa0700 100644 --- a/scripts/check-ci-filter-parity.mjs +++ b/scripts/check-ci-filter-parity.mjs @@ -115,11 +115,13 @@ * ## Wiring * * Invoked from `.github/workflows/lint.yml` as `node scripts/...` directly, both - * legs, rather than through a `pnpm check:*` alias: that alias belongs in root - * `package.json`, declared territory of the @changesets/cli v3 migration lane - * (#9465) while it runs. The self-test asserts that wiring against the workflow - * text -- a gate that exists and is not scheduled is the same dormant shape from - * the other side. + * legs, rather than through a `pnpm check:*` alias: see the GATE INVOCATION + * IDIOM note at the top of that file, which states the reasons once. It is NOT + * because root `package.json` is off limits -- that reading of the #9465 fence + * is false, and the note carries the fence's verbatim scope so this docblock + * does not have to: restating it is how the wrong reading spread (#10894). + * The self-test asserts that wiring against the workflow text -- a gate that + * exists and is not scheduled is the same dormant shape from the other side. */ import { readFileSync } from 'node:fs'; @@ -630,7 +632,7 @@ export async function selfTest() { failures.push(`cannot read .github/workflows/lint.yml to verify wiring: ${err?.code ?? err?.message}`); } if (lint !== null) { - assert(lint.includes(`node ${SELF}\n`), `wiring: lint.yml invokes ${SELF} (no root package.json alias -- #9465 fence)`); + assert(lint.includes(`node ${SELF}\n`), `wiring: lint.yml invokes ${SELF} directly (lint.yml's GATE INVOCATION IDIOM note, not a package.json fence)`); assert(lint.includes(`node ${SELF} --self-test`), 'wiring: lint.yml runs the --self-test leg too'); } diff --git a/scripts/check-doc-frontmatter.mjs b/scripts/check-doc-frontmatter.mjs index 3dd8a000dd..6110953376 100644 --- a/scripts/check-doc-frontmatter.mjs +++ b/scripts/check-doc-frontmatter.mjs @@ -208,12 +208,14 @@ * * ## Wiring * - * Invoked from `.github/workflows/lint.yml` as `node scripts/...` directly, - * both legs, rather than through a `pnpm check:*` alias: that alias belongs in - * root `package.json`, declared territory of the @changesets/cli v3 migration - * lane (#9465) while it runs. The self-test asserts that wiring against the - * workflow text -- a gate that exists and is not scheduled is the same dormant - * shape from the other side. + * Invoked from `.github/workflows/lint.yml` as `node scripts/...` directly, both + * legs, rather than through a `pnpm check:*` alias: see the GATE INVOCATION + * IDIOM note at the top of that file, which states the reasons once. It is NOT + * because root `package.json` is off limits -- that reading of the #9465 fence + * is false, and the note carries the fence's verbatim scope so this docblock + * does not have to: restating it is how the wrong reading spread (#10894). + * The self-test asserts that wiring against the workflow text -- a gate that + * exists and is not scheduled is the same dormant shape from the other side. * * Adding the second root needed NO workflow edit: the step already invokes this * script, and `ROOTS` is read from here. `lint.yml` is the repo's busiest file @@ -1220,7 +1222,7 @@ export async function selfTest() { failures.push(`cannot read .github/workflows/lint.yml to verify wiring: ${err.code ?? err.message}`); } if (lint !== null) { - assert(lint.includes(`node ${SELF}\n`), `wiring: lint.yml invokes ${SELF} (no root package.json alias -- #9465 fence)`); + assert(lint.includes(`node ${SELF}\n`), `wiring: lint.yml invokes ${SELF} directly (lint.yml's GATE INVOCATION IDIOM note, not a package.json fence)`); assert(lint.includes(`node ${SELF} --self-test`), 'wiring: lint.yml runs the --self-test leg too'); } diff --git a/scripts/check-platform-checklist.mjs b/scripts/check-platform-checklist.mjs index 11fd17c5fd..920f5b06ba 100644 --- a/scripts/check-platform-checklist.mjs +++ b/scripts/check-platform-checklist.mjs @@ -105,14 +105,17 @@ const err = (file, id, msg) => errors.push(`${file}${id ? ` · ${id}` : ''}: ${m // // The battery runs inline, on every invocation, not only behind `--self-test`, // because a `--self-test` here would otherwise execute NOWHERE: this gate is -// not CI-wired by maintainer decision (README "Operating cadence"), and its -// `pnpm` alias lives in root package.json, declared territory of the -// @changesets/cli v3 lane (#9465) while that runs. A self-test nothing runs is -// the documented defect of #10574/#10573 — CI enforcing the spelling of a -// guarantee while never once checking the guarantee still holds. The battery -// is in-memory string work (~1 ms of a ~270 ms run), so "always" costs nothing -// worth naming, and its assertion count is printed on the OK line: the green -// states how many rows it read and that its own control passed. +// not CI-wired by maintainer decision (README "Operating cadence"), so nothing +// on a PR would ever reach a `--self-test` leg. NOT because its `pnpm` alias is +// unavailable to it: `check:platform-checklist` is already a key in root +// package.json, and the reading that the #9465 fence covers that file is false +// -- the GATE INVOCATION IDIOM note at the top of `.github/workflows/lint.yml` +// carries that lane's verbatim scope, and is not restated here. A self-test +// nothing runs is the documented defect of #10574/#10573 — CI enforcing the +// spelling of a guarantee while never once checking the guarantee still holds. +// The battery is in-memory string work (~1 ms of a ~270 ms run), so "always" +// costs nothing worth naming, and its assertion count is printed on the OK +// line: the green states how many rows it read and that its own control passed. const RUNNER_FILE = join(ROOT, 'docs/qa/platform-checklist/RUNNER.md'); const TRAP_HEADING = '### Trap vocabulary'; diff --git a/scripts/check-skills-token-ratchet.mjs b/scripts/check-skills-token-ratchet.mjs index 23d1d47c0a..0b2aeb3f5c 100644 --- a/scripts/check-skills-token-ratchet.mjs +++ b/scripts/check-skills-token-ratchet.mjs @@ -54,8 +54,11 @@ * nobody edited a file is not a ratchet. * - NO DEPENDENCY. The workspace carries no tokenizer today (checked at * landing: no `tiktoken` / `gpt-tokenizer` / `gpt-3-encoder` in any - * manifest), and root dependencies are fenced (#9465). Adding one to make a - * lint gate's numbers prettier is not a trade this gate needs. + * manifest). Adding one to make a lint gate's numbers prettier is not a + * trade this gate needs. Refused on that merit alone, not by a fence: root + * dependencies as a CLASS are not #9465 territory -- the GATE INVOCATION + * IDIOM note at the top of `.github/workflows/lint.yml` carries that lane's + * verbatim scope, and it is pointed at rather than restated here. * - INDEPENDENTLY REPRODUCIBLE. Anyone can audit a ceiling without running * this script: `ceil($(wc -c < file) / 4)`. A tokenizer's count can only be * checked by re-running the tokenizer.