Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion scripts/check-org-identifier.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,34 @@ import { maskComments } from './js-comment-mask.mjs';
import { isEntrypoint } from './invoked-as.mjs';

const ROOTS = ['examples', 'apps', 'packages'];

/**
* The population this gate enumerates, declared for
* `scripts/pm/dispatch-gates.mjs`.
*
* `sourceFiles` runs `git ls-files -- examples apps packages` — three SUBTREES,
* seeded from the `ROOTS` constant above. The derivation reads SOURCE TEXT and
* `hintCovers` refuses a bare single-segment literal by design (accepting them
* was priced at +139084 fabricated (gate, file) pairs, because these three words
* are path COMPONENTS in dozens of gates that never read those roots), so this
* gate declared nothing and was scored `undetermined` for EVERY card: it reached
* no dispatch brief and no `--commands` harvest while CI ran it on every pull
* request.
*
* ⛔ Not a whole-tree marker, and this gate is the reason that boundary is
* written down. It was held OUT of the whole-tree bucket with a
* `ROOT_WALK_RESIDUE_LEDGER` row precisely because the liveness predicate that
* vouches for a whole-tree declaration sees a `git ls-files` call and cannot
* tell a three-subtree enumeration apart from a repo-wide one — so a whole-tree
* marker here would be exactly the mis-declaration that predicate cannot catch.
* That ledger row named this declaration as the remedy; landing it clears the
* row, and the two moves are coupled by construction (a stale exclusion reds).
*
* The self-test derives the coupling from `ROOTS` on both sides rather than
* re-spelling it, so widening or renaming a root cannot leave this declaration
* describing the old population.
*/
const ROOT_DIR_WATCH_HINTS = ['examples/**', 'apps/**', 'packages/**'];
const EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.cts', '.mts'];
const EXCLUDED = /(^|\/)(node_modules|dist|build|\.next|\.turbo)\//;
// Dropped WHOLESALE: absence pins and fixtures that CONSTRUCT the removed
Expand Down Expand Up @@ -614,11 +642,12 @@ let selfTestReachedVerdict = false;
// to find what stopped registering.
const SELF_TEST_BATTERIES = Object.freeze({
'check-org-identifier self-test': 31,
'the dispatch-gates population declaration': 4,
});

// DELETING an entry silences that battery's floor exactly as effectively as
// zeroing it, so the roster's own size is pinned too.
const SELF_TEST_BATTERY_FLOOR = 1;
const SELF_TEST_BATTERY_FLOOR = 2;

// The key an assertion is filed under when no battery is open. It is not a
// declared battery, so it reds by the same set difference rather than silently
Expand Down Expand Up @@ -750,6 +779,35 @@ check(() => {
}
});

// ── The dispatch-gates population declaration ────────────────────────────
battery('the dispatch-gates population declaration');
const declFail = (msg) => { console.error(` ✗ ${msg}`); failed++; };
check(() => {
if (!ROOTS.filter((r) => !r.includes('/')).every((r) => ROOT_DIR_WATCH_HINTS.includes(`${r}/**`))) {
declFail('a separator-less ROOT is not declared in the subtree spelling — a bare root is refused '
+ 'as too generic, so the hint extractor reads nothing and this gate returns to scoring '
+ '`undetermined` for every card.');
}
});
check(() => {
if (!ROOT_DIR_WATCH_HINTS.every((h) => ROOTS.includes(h.replace(/\/\*+$/, '')))) {
declFail('ROOT_DIR_WATCH_HINTS declares a root this gate does not enumerate — a declaration that '
+ 'has drifted from the scan replaces a silent gate with a lying one.');
}
});
check(() => {
if (ROOTS.some((r) => ROOT_DIR_WATCH_HINTS.includes(r))) {
declFail('the declared form is a ROOTS entry — the bare form is what `git ls-files` takes, and it '
+ 'is exactly what the hint extractor cannot read.');
}
});
check(() => {
if (ROOT_DIR_WATCH_HINTS.length !== ROOTS.length) {
declFail('the declaration is not one hint per enumerated root — a short list reads exactly like '
+ 'the undetermined verdict it exists to leave.');
}
});

// ── The floor: every declared battery RAN, and ran its cases (#13489) ────
//
// Evaluated after every battery has had its chance and BEFORE the verdict, so
Expand Down
66 changes: 62 additions & 4 deletions scripts/check-sdui-manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,57 @@
import { createHash } from 'node:crypto';
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';
import { dirname, join, sep } from 'node:path';
import { fileURLToPath } from 'node:url';

import { isEntrypoint } from './invoked-as.mjs';

const DEFAULT_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');

/** The three files `checkTree` opens, repo-relative. */
const READ_PATHS = {
artefact: 'sdui.manifest.json',
record: join('scripts', 'sdui-manifest.record.json'),
pin: '.objectui-sha',
};

/**
* The population this gate reads, declared for `scripts/pm/dispatch-gates.mjs`.
*
* `checkTree` opens exactly three files. None of them was visible to the
* derivation: it reads SOURCE TEXT, and a literal with no separator is refused
* by `hintCovers` as too generic (`sdui.manifest.json`), while `.objectui-sha`
* is not one of the dot-prefixed names the extractor admits and the record path
* is assembled with `join()`. So both of this gate's CI invocations — the scan
* and its `--self-test` — were scored `undetermined` for EVERY card, absent from
* every dispatch brief and every `--commands` harvest, while CI ran them on each
* pull request. That cost is sharpest here: the cards that implicate this gate
* are exactly the ones that move the objectui pin or regenerate the manifest.
*
* `ROOT_WATCH_HINTS` is the mixed-roots spelling of the idiom, which is what
* this population is: two repo-ROOT files and one under `scripts/`. The
* repo-root pair carries the `/**` suffix because a bare single-segment literal
* is refused; the collapse reduces each one back to the single file it names and
* to nothing else.
*
* ⛔ Not a whole-tree marker, and not `scripts/**`: three files are three files.
*
* The self-test derives the coupling from `READ_PATHS` — the same object
* `checkTree` reads — so a moved or added read reds here rather than leaving the
* declaration describing the old population.
*/
const ROOT_WATCH_HINTS = [
'sdui.manifest.json/**',
'scripts/sdui-manifest.record.json',
'.objectui-sha/**',
];

/** Gate one tree. Returns a list of problems; empty = green. */
export function checkTree(root) {
const problems = [];
const artefactPath = join(root, 'sdui.manifest.json');
const recordPath = join(root, 'scripts', 'sdui-manifest.record.json');
const pinPath = join(root, '.objectui-sha');
const artefactPath = join(root, READ_PATHS.artefact);
const recordPath = join(root, READ_PATHS.record);
const pinPath = join(root, READ_PATHS.pin);

if (!existsSync(artefactPath)) {
problems.push(
Expand Down Expand Up @@ -247,6 +285,26 @@ function selfTest() {
for (const p of problems) console.error(` ${p}`);
}
}
// ── The dispatch-gates population declaration ──────────────────────────
// Filed outside the cases table, deliberately: each table ROW is a declared
// battery here, so an assertion added as a row would owe a roster entry for a
// case that gates nothing about `checkTree`'s verdicts.
const declFail = (message) => { console.error(`✗ self-test: ${message}`); failures++; };
const readPosix = Object.values(READ_PATHS).map((f) => f.split(sep).join('/'));
const declared = ROOT_WATCH_HINTS.map((h) => h.replace(/\/\*+$/, ''));
if (!readPosix.every((f) => declared.includes(f))) {
declFail('a file checkTree reads is not declared for dispatch-gates — an unreadable literal is how '
+ 'this gate came to declare nothing at all, and it scores `undetermined` for every card again.');
}
if (!declared.every((h) => readPosix.includes(h))) {
declFail('ROOT_WATCH_HINTS declares a path this gate does not read — a declaration that has drifted '
+ 'from the reads replaces a silent gate with a lying one.');
}
if (!ROOT_WATCH_HINTS.filter((h) => !h.replace(/\/\*+$/, '').includes('/')).every((h) => h.endsWith('/**'))) {
declFail('a repo-ROOT file is declared without the subtree suffix — a bare single-segment literal is '
+ 'refused by hintCovers as too generic, so it would contribute no hint at all.');
}

// ── The floor: every declared row RAN, and ran its case (#13489) ───────
//
// Evaluated after every row has had its chance and BEFORE the verdict, so the
Expand Down
52 changes: 51 additions & 1 deletion scripts/check-tenant-chokepoint.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
*/

import { readFileSync, existsSync } from 'node:fs';
import { join, relative } from 'node:path';
import { join, relative, sep } from 'node:path';
import { fileURLToPath } from 'node:url';
import { requireDefaultExport } from './import-prerequisite.mjs';
const ts = await requireDefaultExport('typescript', () => import('typescript'), import.meta.url);
Expand All @@ -124,6 +124,38 @@ const SCAN_FILES = [
join('packages', 'drivers', 'driver-turso', 'src', 'turso-driver.ts'),
];

/**
* The population this gate reads, declared for `scripts/pm/dispatch-gates.mjs`.
*
* `SCAN_FILES` is assembled with `join()`, one SEGMENT per literal, so the
* derivation — which reads SOURCE TEXT — saw a handful of bare words and no path
* at all. This gate was scored `undetermined` for EVERY card: absent from every
* dispatch brief and every `--commands` harvest, while CI ran it on each pull
* request. Worse than the usual cost, because this gate's population is THREE
* FILES: the cards that actually implicate it are rare and precisely nameable,
* and it was reaching none of them.
*
* The spelling is `DECLARED_WATCH_HINTS` rather than the directory idiom: this
* is an enumerated population, not a walked subtree, and each hint is a whole
* repo-relative FILE path — which carries a separator, so `hintCovers` reads it
* without a glob suffix.
*
* ⛔ Not `packages/drivers/**`, and not a whole-tree marker. Both would put this
* gate on cards it does not read a byte for; a lead that is wrong on thousands
* of files is worse than the silence it replaces.
*
* The self-test derives the coupling from `SCAN_FILES` on both sides rather than
* re-spelling it, so a driver added to or removed from the family cannot leave
* this declaration describing the old population. The POSIX normalisation is
* load-bearing: `join()` yields a platform separator, and the declaration is
* read as text by a scanner that only knows `/`.
*/
const DECLARED_WATCH_HINTS = [
'packages/drivers/driver-sql/src/sql-driver.ts',
'packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver.ts',
'packages/drivers/driver-turso/src/turso-driver.ts',
];

/**
* The floor a real scan must clear. A scan that silently stops matching reports
* "clean" while reading nothing (#4690), and this gate's whole value is that it
Expand Down Expand Up @@ -522,6 +554,24 @@ function selfTest() {
assert(builders.length === 0, 'the empty fixture must discover no builders');
}

// ── the dispatch-gates population declaration ────────────────────────────
const scannedPosix = SCAN_FILES.map((f) => f.split(sep).join('/'));
assert(
scannedPosix.every((f) => DECLARED_WATCH_HINTS.includes(f)),
'every SCAN_FILES entry is declared for dispatch-gates — a join()-assembled path is invisible to '
+ 'the hint extractor, which is how this gate came to declare nothing at all',
);
assert(
DECLARED_WATCH_HINTS.every((h) => scannedPosix.includes(h)),
'and nothing is declared that this gate does not read — a declaration that has drifted from the '
+ 'scan replaces a silent gate with a lying one',
);
assert(
DECLARED_WATCH_HINTS.every((h) => !h.includes('*')),
'the declaration stays file-exact — a `packages/drivers/**` widening would name this gate on '
+ 'cards it does not read a byte for',
);

// ── The floor: every declared battery RAN, and ran its cases (#13489) ────
//
// Evaluated after every battery has had its chance and BEFORE the verdict, so
Expand Down
7 changes: 0 additions & 7 deletions scripts/pm/dispatch-gates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2341,13 +2341,6 @@ export function wholeTreePopulationRefusal(entry) {
* reds too: a stale exclusion is an exclusion nobody is measuring any more.
*/
export const ROOT_WALK_RESIDUE_LEDGER = [
[
'check:org-identifier',
'its enumeration is `git ls-files -- examples apps packages` (the ROOTS constant) — three SUBTREES, not the '
+ 'tree. The liveness predicate selects it on limb A and is documented as too weak to tell that apart, so a '
+ 'whole-tree marker here would be precisely the mis-declaration that predicate cannot catch. Its remedy is '
+ 'the ordinary ROOT_DIR_WATCH_HINTS declaration naming those three roots, after which it is MATCHED here.',
],
[
'scripts/check-console-intercept-disarm.mjs',
'its `scan(REPO_ROOT)` walks `workspacePackageDirs(root)` — every workspace PACKAGE ROOT\'s package.json and '
Expand Down
12 changes: 12 additions & 0 deletions scripts/publish-smoke-pack.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@
* reading a copy that a gate keeps honest, rather than the thing itself.
*/

// ## The dispatch-gates population
//
// `main()` shells out to `pnpm -r list` and `pnpm pack`; it opens no path this
// file names, and it runs only from `scripts/publish-smoke.sh` during a release.
// The family CI schedules on a pull request is `check:publish-smoke-pin`, which
// is this file's `--self-test`: pure fixtures, no workspace, no network, no
// tracked file. There is no path population for a card to implicate, so the
// marker is the honest declaration -- and `packages/**` would be the costly
// error, naming this family on thousands of cards for reads it never performs.
//
// dispatch-gates: no-path-population -- check:publish-smoke-pin runs this packer's --self-test against in-memory fixtures; the workspace enumeration and the pack itself belong to the release smoke, which no pull request schedules

import { execFile } from 'node:child_process';
import { mkdirSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
Expand Down
13 changes: 13 additions & 0 deletions scripts/run-with-stall-guard.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,19 @@
// Exit status: the child's own code when it finishes; 75 on a declared stall;
// 1 when the child dies on a signal this guard did not send.

// ## The dispatch-gates population
//
// This is a RUNNER, not a scanner. Its reads are `/proc` (process state for the
// stall verdict) and, when CI passes `--report-dir`, a runner temp directory of
// diagnostic reports -- neither is in the repository, and no card can contain
// either. The family CI schedules on a pull request is `check:stall-guard`,
// which is this file's `--self-test`. So there is no path population to declare,
// and the marker says so rather than leaving the family in the unexamined pile.
// A card that edits THIS file is already led to `check:stall-guard-budget`,
// which declares this path as part of its own population.
//
// dispatch-gates: no-path-population -- this is a process runner: it reads /proc and, when given --report-dir, a runner temp dir, never a file in the repository; check:stall-guard is its --self-test

import { spawn } from 'node:child_process';
import {
createWriteStream,
Expand Down
16 changes: 16 additions & 0 deletions scripts/sync-docs-image-tags.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@
// historical facts across three files with nothing downstream to complain, so
// --self-test asserts a clean corpus is left BYTE-IDENTICAL, with no write at all.

// ## The dispatch-gates population, read rather than assumed
//
// This file is a REWRITER, and in rewrite mode it opens the three doc surfaces
// plus `packages/cli/package.json` -- all of them inherited from
// `check-docs-image-tag.mjs`, which declares them and is judged on them. But the
// family CI schedules is `check:docs-image-tag-sync`, and both of its call sites
// (lint.yml and release.yml) run `--self-test`, which works entirely inside a
// `mkdtempSync` fixture tree and reads not one tracked file. So there is no
// population for a card to implicate, and the honest declaration is the marker
// rather than a hint set copied from the gate next door -- a hint here would
// name this family on every `content/docs/**` card for reads its CI invocation
// never performs. The SURFACES themselves are already declared where they are
// read: `check:docs-image-tag` carries them.
//
// dispatch-gates: no-path-population -- both CI call sites (lint.yml, release.yml) run this rewriter's --self-test, which works inside a mkdtemp fixture tree and reads no tracked file; the doc surfaces and the version source belong to check:docs-image-tag, which declares them

import { readFileSync, writeFileSync, mkdirSync, mkdtempSync, rmSync, statSync, existsSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';
Expand Down
Loading