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
35 changes: 35 additions & 0 deletions scripts/gen-sdui-reference.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ import { isEntrypoint } from './invoked-as.mjs';
const REPO_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const MANIFEST_PATH = 'sdui.manifest.json';
const OUT_DIR = 'content/docs/ui/components';

/**
* The repo-root file this generator reads, declared for `scripts/pm/dispatch-gates.mjs`.
*
* The derivation reads SOURCE TEXT, and `MANIFEST_PATH` above is a literal with
* no separator, which `hintCovers` refuses as too generic. `OUT_DIR` was always
* visible and the manifest was not, so a diff that changed only the manifest
* never derived `pnpm check:sdui-reference` -- the one diff this gate exists to
* catch, since a regenerated manifest beside a stale reference reds it in CI.
*
* The `/**` suffix is the repo-root-file spelling of the idiom (the same one
* `scripts/check-sdui-manifest.mjs` declares for this file): a bare
* single-segment literal builds no hint, and the collapse reduces this one back
* to the single file it names and to nothing else. The self-test holds it equal
* to `MANIFEST_PATH`, so a moved read reds there instead of leaving the
* declaration describing the old file.
*/
const ROOT_FILE_WATCH_HINTS = ['sdui.manifest.json/**'];
const URL_BASE = '/docs/ui/components';
const COMMAND = 'node scripts/gen-sdui-reference.mjs';

Expand Down Expand Up @@ -657,6 +675,23 @@ function selfTest() {
}
}

// ── The dispatch-gates population declaration ──────────────────────────
// Outside the cases table on purpose: each row there is a declared battery
// about the rendering, and this asserts what the derivation can see.
const declFail = (message) => {
console.error(`✗ self-test: ${message}`);
failed += 1;
};
const declaredReads = ROOT_FILE_WATCH_HINTS.map((h) => h.replace(/\/\*+$/, ''));
if (declaredReads.length !== 1 || declaredReads[0] !== MANIFEST_PATH) {
declFail(`ROOT_FILE_WATCH_HINTS declares ${JSON.stringify(declaredReads)}, not the manifest this script reads `
+ `(${MANIFEST_PATH}) — an undeclared read is how a manifest-only diff stopped deriving this gate.`);
}
if (!ROOT_FILE_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.');
}

const floorFailure = (message) => {
console.error(`✗ self-test floor: ${message}`);
failed += 1;
Expand Down
9 changes: 9 additions & 0 deletions scripts/pm/dispatch-gates.self-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3525,6 +3525,15 @@ export function selfTest({ tier = 'full' } = {}) {
t('a one-root declaration does not reach the other root file', !proseHints.some((h) => hintCovers(h, 'CLAUDE.md')));
const anchorRootHints = extractWatchHints(readFileSync(nodePath.join(ROOT, 'scripts/check-doc-anchors.mjs'), 'utf8'), 'scripts/check-doc-anchors.mjs');
t('and the doc-anchors pair claims neither instruction file', !anchorRootHints.some((h) => hintCovers(h, 'AGENTS.md') || hintCovers(h, 'CLAUDE.md')));
// The same class on a non-instruction root file, driven end to end through the
// live fleet: `check:sdui-reference` reads the repo-root `sdui.manifest.json`
// and reds in CI when the manifest moves without the reference, so the
// manifest alone must place it. Fixed by the gate's own declaration, never by
// admitting bare root literals here. If the gate stops reading the manifest,
// delete these cases with the declaration.
const sduiReference = discoverFamilies().byCheck.get('check:sdui-reference');
t('a diff of sdui.manifest.json alone derives pnpm check:sdui-reference', Boolean(sduiReference) && placeFamily(sduiReference, ['sdui.manifest.json']).verdict === 'matched');
t('and that declaration claims no same-named file inside a directory', Boolean(sduiReference) && placeFamily(sduiReference, ['examples/sdui.manifest.json']).verdict !== 'matched');

// A THIRD shape of the same class, and the one with the worst failure
// direction (#13207): a gate whose declared population was its OWN GUARDED
Expand Down
Loading