From 67581c042b948a73b0f6e0e5859c45fbdb35e1e3 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 12:28:56 +0000 Subject: [PATCH] refactor(devx): the eight remaining comment-mask callers take the projection from js-comment-mask `js-comment-mask.mjs` publishes `maskCommentsAndLiterals` (#15594, PR #15774), which converted the two callers that ruling named. Eight more spelled the same `comment | literal` -> `blank` composition under eight more names, each composing the shared scanner and carrying no scanning logic of its own, none with a shared pin. All eight now read the module's export. Three return a PAIR of projections and keep their return shape as a wrapper over the exports rather than a straight substitution: `maskedProjections` (`check-test-source-alias`), `projections` (`check-error-status-conformance`) and `project` (`check-docs-section-name`, which still reads `scanSource` for the raw `comment`/`literal` flags one of its rules indexes directly). Two keep their own name for the projection through an import alias, because the file's self-test row labels and its prose read that name: `codeOnly` in `check-parse-guard` and in `docs-audit/affected-docs`. `measure-self-test-floor.mjs` carried a local copy under the SHARED NAME -- a local definition, not a completed conversion -- so the import replaces it and the same name is re-exported. Each deleted docblock's gate-specific facts move with the conversion rather than becoming a stale assertion about a function that is gone. Behaviour byte-identical, proven per gate by diffing plain and `--self-test` output before and after: 16 runs, 16 empty diffs, exit 0 on every side. Part of #15776 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8 --- scripts/check-console-intercept-disarm.mjs | 31 ++--- scripts/check-docs-section-name.mjs | 11 +- scripts/check-error-status-conformance.mjs | 10 +- scripts/check-parse-guard.mjs | 15 +-- scripts/check-stack-collection-maps.mjs | 146 +++++++++++---------- scripts/check-test-source-alias.mjs | 11 +- scripts/docs-audit/affected-docs.mjs | 26 ++-- scripts/measure-self-test-floor.mjs | 41 +++--- 8 files changed, 136 insertions(+), 155 deletions(-) diff --git a/scripts/check-console-intercept-disarm.mjs b/scripts/check-console-intercept-disarm.mjs index 8ca99a84a8..d718a448a8 100644 --- a/scripts/check-console-intercept-disarm.mjs +++ b/scripts/check-console-intercept-disarm.mjs @@ -89,26 +89,19 @@ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, import { dirname, join, resolve } from 'node:path'; import { tmpdir } from 'node:os'; import { fileURLToPath } from 'node:url'; -import { blank, scanSource } from './js-comment-mask.mjs'; +import { maskCommentsAndLiterals } from './js-comment-mask.mjs'; import { isEntrypoint } from './invoked-as.mjs'; -/** - * Comments AND string/template/regex content blanked, offsets kept. This gate - * looks for a bare code-position `disableConsoleIntercept: true`, so unlike - * the gates whose signal IS a string literal, a quoted spelling here is never - * the real setting — it is prose (an error message, a doc snippet) and - * blanking it keeps prose from satisfying the check. The boundary this - * accepts: a config spelling the KEY as a quoted property - * (`'disableConsoleIntercept': true`) reds the gate even though vitest would - * honour it — the failure is loud, names the file, and the remedy is the - * unquoted spelling every other config uses. - */ -function maskProse(source) { - const { comment, literal } = scanSource(source); - const flags = new Uint8Array(comment.length); - for (let i = 0; i < flags.length; i++) flags[i] = comment[i] | literal[i]; - return blank(source, flags); -} +// Why this gate reads `maskCommentsAndLiterals` — the tree's one +// comments+literals projection, imported rather than re-derived here (#15776). +// This gate looks for a bare code-position `disableConsoleIntercept: true`, so +// unlike the gates whose signal IS a string literal, a quoted spelling here is +// never the real setting — it is prose (an error message, a doc snippet) and +// blanking it keeps prose from satisfying the check. The boundary this accepts: +// a config spelling the KEY as a quoted property +// (`'disableConsoleIntercept': true`) reds the gate even though vitest would +// honour it — the failure is loud, names the file, and the remedy is the +// unquoted spelling every other config uses. const HERE = dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = resolve(HERE, '..'); @@ -261,7 +254,7 @@ export function scan(root) { ); continue; } - const masked = maskProse(readFileSync(join(dir, configName), 'utf8')); + const masked = maskCommentsAndLiterals(readFileSync(join(dir, configName), 'utf8')); if (REARM_RE.test(masked)) { findings.push( `${rel(root, dir)}/${configName}: sets disableConsoleIntercept: FALSE — this ` + diff --git a/scripts/check-docs-section-name.mjs b/scripts/check-docs-section-name.mjs index 402f764ebe..8be6a96acd 100644 --- a/scripts/check-docs-section-name.mjs +++ b/scripts/check-docs-section-name.mjs @@ -215,7 +215,7 @@ import YAML from 'yaml'; import { fencedBlocks } from './check-react-page-adapter-contract.mjs'; import { isEntrypoint } from './invoked-as.mjs'; -import { blank, scanSource } from './js-comment-mask.mjs'; +import { maskCommentsAndLiterals, scanSource } from './js-comment-mask.mjs'; // ── The self-test's own battery roster and floor (#13489) ────────────────── // @@ -444,14 +444,17 @@ export function docsFiles(root) { /** * The two projections of one scan. Both share byte offsets with `body`. * + * `codeOnly` is `js-comment-mask.mjs`'s own `maskCommentsAndLiterals` (#15776), + * not a composition re-derived here; the raw `comment`/`literal` flags are what + * this gate still needs `scanSource` for (a rule below reads `literal[i] === 0` + * directly), and they address `body` at the same offsets the mask does. + * * @param {string} body * @returns {{ codeOnly: string, comment: Uint8Array, literal: Uint8Array }} */ export function project(body) { const { comment, literal } = scanSource(body); - const both = new Uint8Array(body.length); - for (let i = 0; i < body.length; i++) both[i] = comment[i] || literal[i] ? 1 : 0; - return { codeOnly: blank(body, both), comment, literal }; + return { codeOnly: maskCommentsAndLiterals(body), comment, literal }; } /** diff --git a/scripts/check-error-status-conformance.mjs b/scripts/check-error-status-conformance.mjs index 2696baad02..07d5536b15 100644 --- a/scripts/check-error-status-conformance.mjs +++ b/scripts/check-error-status-conformance.mjs @@ -154,7 +154,7 @@ // `scripts/error-status-unpinned-baseline.json`; a NEW one fails the gate, and a // row that becomes pinned fails it too (ratchet down with `--update`). import { readdirSync, readFileSync, writeFileSync, statSync, existsSync } from 'node:fs'; -import { maskComments, scanSource, blank } from './js-comment-mask.mjs'; +import { maskComments, maskCommentsAndLiterals } from './js-comment-mask.mjs'; import { join, relative } from 'node:path'; import { isEntrypoint } from './invoked-as.mjs'; @@ -401,7 +401,8 @@ function classBodies(src) { const lineOf = (src, idx) => src.slice(0, idx).split('\n').length; /** - * The two projections a rule may read, from ONE scan of the source. + * The two projections a rule may read, both `js-comment-mask.mjs`'s own exports + * (#15776) rather than a composition re-derived here. * * `src` comments blanked, string/template/regex CONTENT intact — what * every rule matches on, because a gate's signal (`code: @@ -414,10 +415,7 @@ const lineOf = (src, idx) => src.slice(0, idx).split('\n').length; * mask, so a line number read off either is true of the original. */ function projections(raw) { - const { comment, literal } = scanSource(raw); - const both = new Uint8Array(raw.length); - for (let k = 0; k < both.length; k++) both[k] = comment[k] || literal[k]; - return { src: blank(raw, comment), structural: blank(raw, both) }; + return { src: maskComments(raw), structural: maskCommentsAndLiterals(raw) }; } /** diff --git a/scripts/check-parse-guard.mjs b/scripts/check-parse-guard.mjs index 5bb4829b60..d68927c49f 100644 --- a/scripts/check-parse-guard.mjs +++ b/scripts/check-parse-guard.mjs @@ -122,7 +122,12 @@ import { join, relative, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { isEntrypoint } from './invoked-as.mjs'; -import { blank, scanSource } from './js-comment-mask.mjs'; +// This gate's `codeOnly` IS the tree's one comments+literals projection, not a +// local re-derivation of it (#15776): `js-comment-mask.mjs` owns the projections +// and its `--self-test` pins this one. The name stays because this gate's prose, +// its self-test rows and its findings all read `codeOnly`. +import { maskCommentsAndLiterals as codeOnly } from './js-comment-mask.mjs'; +export { codeOnly }; // ── The self-test's own battery roster and floor (#13489) ────────────────── // @@ -382,14 +387,6 @@ function walkOutside(dir, out = []) { return out; } -/** Code only: comments, strings, templates and regex literals all blanked. */ -export function codeOnly(source) { - const { comment, literal } = scanSource(source); - const both = new Uint8Array(comment.length); - for (let i = 0; i < both.length; i++) both[i] = comment[i] || literal[i]; - return blank(source, both); -} - function lineOf(source, index) { return source.slice(0, index).split('\n').length; } diff --git a/scripts/check-stack-collection-maps.mjs b/scripts/check-stack-collection-maps.mjs index fb7c167fed..dbbd54c675 100644 --- a/scripts/check-stack-collection-maps.mjs +++ b/scripts/check-stack-collection-maps.mjs @@ -97,11 +97,80 @@ import { readFileSync, existsSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join, resolve } from 'node:path'; import { isEntrypoint } from './invoked-as.mjs'; -import { blank, scanSource } from './js-comment-mask.mjs'; +import { maskCommentsAndLiterals } from './js-comment-mask.mjs'; const here = dirname(fileURLToPath(import.meta.url)); const repoRoot = resolve(here, '..'); +// ─────────────────────────────────────────────────────────────────────────── +// The mask every scan below reads -- IMPORTED, not re-derived (#15776) +// ─────────────────────────────────────────────────────────────────────────── +// +// `maskCommentsAndLiterals` is the tree's one comments+literals projection and +// `js-comment-mask.mjs` owns it; this gate used to spell a private `maskLiterals` +// that composed the same shared scanner by hand. What follows is the fact that +// belongs to THIS gate -- why a bracket counter here may read nothing else, and +// what the conversion onto the shared scanner measured when it happened. +// +// Blank out everything a bracket counter must not read: comment bodies, string +// and template contents, and regex literals. Returns a string of the SAME LENGTH +// as the input, so every index still addresses the original source — callers +// count structure on the mask and slice text from the original. +// +// Length-preserving masking rather than a `strip`: the first draft of this gate +// stripped comments and counted brackets over the rest, and one unbalanced paren +// inside PROSE — `.describe('Screen Flows (ADR-0019)')` — closed the +// `ObjectStackDefinitionSchema` literal 14 collections early. The gate then +// reconciled all seven sites against a truncated source of truth and reported +// 114 deviations, every one of them its own. A parser that fails toward "less +// schema" makes every consumer look wrong, which is the loudest possible way to +// be useless. +// +// String DELIMITERS survive (their contents do not), so a quoted object key and +// an array of string literals are both still locatable by index. +// +// ## CONVERTED onto the shared scanner (#13143) +// +// This body used to be a private left-to-right scanner written out here, and it +// was the one piece of comment-scanning code in this directory that no gate +// could see. `check-comment-mask-adoption.mjs` watches for exactly this shape +// and walks `packages` + `examples` only; `check-parse-guard.mjs` walks this +// directory for a different subject (the three TypeScript parser entry points). +// A private stripper here sits inside one gate's population and outside its +// subject, and inside the other's subject and outside its population, so +// nothing reds. Routing through the shared module is the half of that gap a +// caller can close on its own. +// +// A conversion is a MEASUREMENT rather than a mechanical edit, so here is the +// reading. The private scanner against `scanSource()`'s `comment | literal` +// projection, over THE POPULATION THIS GATE ACTUALLY READS (the seven SITE +// files plus `stack.zod.ts`, 1,028,984 chars): 3 of the 8 files disagree, 49 +// spans, 247 characters. Two classes, and only one of them is a defect. +// +// - 18 spans are a PROJECTION difference and nothing else: the private copy +// blanked a regex literal's slash delimiters, the shared scanner keeps them +// as code. No bracket is a slash, so no caller here could ever see it. +// - 31 spans are the private scanner mis-reading a NESTED TEMPLATE. It closed +// an outer template at the first backtick inside a `${...}`, which flipped +// the parity of every backtick after it and handed the bracket counter 20 +// bracket characters out of the interiors of string and template literals. +// Both files it happens in are live SITE files: `packages/objectql/src/ +// engine.ts` and `packages/metadata/src/plugin.ts`. That is the same family +// as the `(ADR-0019)` incident above, arriving through a different door. +// +// Both directions of that defect are pinned in `--self-test` on synthetic +// bodies, because today's tree happens to punish neither: a nested template +// holding a `]` makes `stringArrayItems` DROP a real key, and one holding a +// quote makes it FABRICATE `${v}` as an enumerated key. The gate's verdict does +// NOT move on this tree -- `--list` is byte for byte identical before and after +// -- which is a fact about where this tree's nested templates sit, not a reason +// the private copy was safe. +// +// The instrument was shown able to fail before its empty results were read as +// agreement: the naive two-regex pair diffed against the shared scanner over +// the same eight files disagrees on 8 of 8, and the shared scanner diffed +// against itself returns nothing. + // ─────────────────────────────────────────────────────────────────────────── // Extraction -- pure, over source text // ─────────────────────────────────────────────────────────────────────────── @@ -124,7 +193,7 @@ const repoRoot = resolve(here, '..'); export function sliceBody(source, anchor, from = 0) { const at = source.indexOf(anchor, from); if (at === -1) return null; - const mask = maskLiterals(source); + const mask = maskCommentsAndLiterals(source); const openAt = at + anchor.length - 1; const open = source[openAt]; const close = open === '{' ? '}' : ']'; @@ -140,79 +209,12 @@ export function sliceBody(source, anchor, from = 0) { return null; } -/** - * Blank out everything a bracket counter must not read: comment bodies, string - * and template contents, and regex literals. Returns a string of the SAME LENGTH - * as the input, so every index still addresses the original source — callers - * count structure on the mask and slice text from the original. - * - * Length-preserving masking rather than a `strip`: the first draft of this gate - * stripped comments and counted brackets over the rest, and one unbalanced paren - * inside PROSE — `.describe('Screen Flows (ADR-0019)')` — closed the - * `ObjectStackDefinitionSchema` literal 14 collections early. The gate then - * reconciled all seven sites against a truncated source of truth and reported - * 114 deviations, every one of them its own. A parser that fails toward "less - * schema" makes every consumer look wrong, which is the loudest possible way to - * be useless. - * - * String DELIMITERS survive (their contents do not), so a quoted object key and - * an array of string literals are both still locatable by index. - * - * ## CONVERTED onto the shared scanner (#13143) - * - * This body used to be a private left-to-right scanner written out here, and it - * was the one piece of comment-scanning code in this directory that no gate - * could see. `check-comment-mask-adoption.mjs` watches for exactly this shape - * and walks `packages` + `examples` only; `check-parse-guard.mjs` walks this - * directory for a different subject (the three TypeScript parser entry points). - * A private stripper here sits inside one gate's population and outside its - * subject, and inside the other's subject and outside its population, so - * nothing reds. Routing through the shared module is the half of that gap a - * caller can close on its own. - * - * A conversion is a MEASUREMENT rather than a mechanical edit, so here is the - * reading. The private scanner against `scanSource()`'s `comment | literal` - * projection, over THE POPULATION THIS GATE ACTUALLY READS (the seven SITE - * files plus `stack.zod.ts`, 1,028,984 chars): 3 of the 8 files disagree, 49 - * spans, 247 characters. Two classes, and only one of them is a defect. - * - * - 18 spans are a PROJECTION difference and nothing else: the private copy - * blanked a regex literal's slash delimiters, the shared scanner keeps them - * as code. No bracket is a slash, so no caller here could ever see it. - * - 31 spans are the private scanner mis-reading a NESTED TEMPLATE. It closed - * an outer template at the first backtick inside a `${...}`, which flipped - * the parity of every backtick after it and handed the bracket counter 20 - * bracket characters out of the interiors of string and template literals. - * Both files it happens in are live SITE files: `packages/objectql/src/ - * engine.ts` and `packages/metadata/src/plugin.ts`. That is the same family - * as the `(ADR-0019)` incident above, arriving through a different door. - * - * Both directions of that defect are pinned in `--self-test` on synthetic - * bodies, because today's tree happens to punish neither: a nested template - * holding a `]` makes `stringArrayItems` DROP a real key, and one holding a - * quote makes it FABRICATE `${v}` as an enumerated key. The gate's verdict does - * NOT move on this tree -- `--list` is byte for byte identical before and after - * -- which is a fact about where this tree's nested templates sit, not a reason - * the private copy was safe. - * - * The instrument was shown able to fail before its empty results were read as - * agreement: the naive two-regex pair diffed against the shared scanner over - * the same eight files disagrees on 8 of 8, and the shared scanner diffed - * against itself returns nothing. - */ -export function maskLiterals(source) { - const { comment, literal } = scanSource(source); - const both = new Uint8Array(source.length); - for (let i = 0; i < source.length; i++) both[i] = comment[i] | literal[i]; - return blank(source, both); -} - /** * Top-level keys of an object-literal body, each with its value's source text. * Depth-aware: a nested literal never contributes its own keys. */ export function objectEntries(body) { - const mask = maskLiterals(body); + const mask = maskCommentsAndLiterals(body); const out = []; let depth = 0; let i = 0; @@ -255,7 +257,7 @@ export function objectEntries(body) { /** String literals at depth 0 of an array-literal body. */ export function stringArrayItems(body) { - const mask = maskLiterals(body); + const mask = maskCommentsAndLiterals(body); const out = []; let depth = 0; for (let i = 0; i < body.length; i++) { @@ -287,7 +289,7 @@ export function stringArrayItems(body) { * answer at all, not to rescue the gate from a silent pass it never had. */ export function tupleFirstItems(body) { - const mask = maskLiterals(body); + const mask = maskCommentsAndLiterals(body); const out = []; let depth = 0; let taken = false; diff --git a/scripts/check-test-source-alias.mjs b/scripts/check-test-source-alias.mjs index ca5ff149bd..f704ea80ce 100644 --- a/scripts/check-test-source-alias.mjs +++ b/scripts/check-test-source-alias.mjs @@ -311,7 +311,7 @@ // node scripts/check-test-source-alias.mjs --self-test import { readFileSync, readdirSync, statSync, existsSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; -import { stripComments, scanSource, blank } from './js-comment-mask.mjs'; +import { stripComments, maskComments, maskCommentsAndLiterals } from './js-comment-mask.mjs'; import { join, resolve, relative, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { @@ -809,12 +809,13 @@ const TYPE_QUERY_BEFORE = /\btypeof\s*$/; * thing in both: `commentsOnly` keeps every string intact (the import regex has * to read the specifier), `codeOnly` masks literal CONTENT as well (the brace * scanner must not count a `{` inside a string or a template). + * + * Both are `js-comment-mask.mjs`'s own exports (#15776) rather than a projection + * re-derived here. They agree offset-for-offset because BOTH blank in place -- + * that is the module's contract, not a property of deriving them from one scan. */ function maskedProjections(source) { - const { comment, literal } = scanSource(source); - const both = new Uint8Array(source.length); - for (let i = 0; i < source.length; i++) both[i] = comment[i] || literal[i] ? 1 : 0; - return { commentsOnly: blank(source, comment), codeOnly: blank(source, both) }; + return { commentsOnly: maskComments(source), codeOnly: maskCommentsAndLiterals(source) }; } /** diff --git a/scripts/docs-audit/affected-docs.mjs b/scripts/docs-audit/affected-docs.mjs index 9285076a38..b54025f9b3 100644 --- a/scripts/docs-audit/affected-docs.mjs +++ b/scripts/docs-audit/affected-docs.mjs @@ -201,7 +201,15 @@ import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs'; import { join, relative } from 'node:path'; // The one answer to "is this span a comment, or code?" (#9367). Dependency-free and // side-effect-free on import, so the no-install contract this script runs under holds. -import { blank, maskComments, scanSource } from '../js-comment-mask.mjs'; +// `codeOnly` IS the tree's one comments+literals projection (#15776), imported +// under this file's own name rather than re-derived here: `js-comment-mask.mjs` +// owns the projections and its `--self-test` pins this one. Every scan below and +// the prose that explains them read `codeOnly`, so the name stays. +// +// The quote characters SURVIVE the blanking, which is the property `unreadableIn` +// rides on: a value that still opens with a quote here is one the recognizer or +// `declinedIn` already accounts for, and a value that does not is one nothing has read. +import { maskComments, maskCommentsAndLiterals as codeOnly } from '../js-comment-mask.mjs'; // ── The self-test's own battery roster and floor (#13489) ────────────────── // @@ -2206,22 +2214,6 @@ function scanRouteSurface() { return { conventionFiles, routeSources, sourceFiles, ledgers, ledgerRows, routeSourceByTail }; } -/** - * The source with comments AND string/template/regex CONTENTS blanked, quotes and all other - * code bytes kept in place. Both masks come from the one answer to "is this span code?" - * (`js-comment-mask.mjs`), so this cannot drift from what the rest of the repo means by it. - * - * The quote characters SURVIVE the blanking, which is the property `unreadableIn` rides on: - * a value that still opens with a quote here is one the recognizer or `declinedIn` already - * accounts for, and a value that does not is one nothing has read. - */ -function codeOnly(source) { - const { comment, literal } = scanSource(source); - const both = new Uint8Array(comment.length); - for (let i = 0; i < both.length; i++) both[i] = comment[i] || literal[i]; - return blank(source, both); -} - /** * The spans of every `interface X { … }` / `type X = { … }` declaration in already-blanked * source. This is the EXACT discriminator against the `route: string;` member that all seven diff --git a/scripts/measure-self-test-floor.mjs b/scripts/measure-self-test-floor.mjs index 9805aeff46..5e10963f86 100644 --- a/scripts/measure-self-test-floor.mjs +++ b/scripts/measure-self-test-floor.mjs @@ -138,7 +138,8 @@ import { tmpdir } from 'node:os'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { isEntrypoint } from './invoked-as.mjs'; -import { blank, maskComments, scanSource } from './js-comment-mask.mjs'; +import { maskComments, maskCommentsAndLiterals, scanSource } from './js-comment-mask.mjs'; +export { maskCommentsAndLiterals }; const ROOT = join(fileURLToPath(new URL('.', import.meta.url)), '..'); @@ -277,28 +278,22 @@ export function classifyFloor(code) { // Instrument 2 -- the dynamic verdict-handshake probe // --------------------------------------------------------------------------- -/** - * The source a DEFINITION may be anchored in: comments AND the content of every - * string, template and regex literal blanked, every other byte -- and every - * offset and line number -- left exactly where it was, so a match found here - * slices the ORIGINAL text. - * - * BOTH halves of "where is the definition" read it: `selfTestDefs` below, which - * says WHICH definitions a file holds, and `injectEarlyReturn`, which says where - * ONE of them begins. They are one question asked twice, and asking them of two - * different texts is the drift #14963's repair exists to end (#15574). - * - * ⛔ NOT for the population criterion above, which must keep reading - * `maskComments`. Every `--self-test` dispatch names the flag with a string - * literal, so this mask blanks the dispatch out of every file in the tree; a - * control below pins the two masks to their opposite answers. - */ -export function maskCommentsAndLiterals(source) { - const { comment, literal } = scanSource(source); - const both = new Uint8Array(source.length); - for (let i = 0; i < both.length; i++) both[i] = comment[i] | literal[i]; - return blank(source, both); -} +// The source a DEFINITION may be anchored in is `maskCommentsAndLiterals` -- +// comments AND the content of every string, template and regex literal blanked, +// every other byte (and every offset and line number) left exactly where it was, +// so a match found there slices the ORIGINAL text. This file used to spell that +// projection out itself, under the shared name; it imports the module's export +// now and re-exports it under the same name (#15776). +// +// BOTH halves of "where is the definition" read it: `selfTestDefs` below, which +// says WHICH definitions a file holds, and `injectEarlyReturn`, which says where +// ONE of them begins. They are one question asked twice, and asking them of two +// different texts is the drift #14963's repair exists to end (#15574). +// +// ⛔ NOT for the population criterion above, which must keep reading +// `maskComments`. Every `--self-test` dispatch names the flag with a string +// literal, so this mask blanks the dispatch out of every file in the tree; a +// control below pins the two masks to their opposite answers. /** * Every `/self.?test/i`-named function DEFINED in this source, read from the