Skip to content

Commit 10bd486

Browse files
yinlianghuiclaude
andauthored
test(pm): pin the test-file kind entry for check:cross-package-test-inputs against its own deletion criterion (#12324)
* test(pm): pin the test-file kind entry for check:cross-package-test-inputs against its own deletion criterion The convention-trigger entry this card asked for has been in the table since #10542. What the re-measurement found instead is that the entry now READS redundant against its own stated deletion criterion and is not: since PR #12300 taught hintCovers to read a glob in a non-final segment, the hint route names the gate for 2758 of the 2771 tracked test files (99.5%, against 0-3.3% for its five siblings in this kind) -- through a hint INHERITED from the declaration table the gate imports, where it is one package's declared turbo inputs glob rather than the gate's own population. Records the measurement at the criterion it qualifies, and pins every load-bearing half of it in --self-test: the residue class (no test file outside the packages tree, no .tsx inside it, nothing under apps), the live specimens, the inheritance provenance, and that the KIND still names the gate for all of them. Both routes are kept -- two routes to one gate is redundancy, not a bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6 * docs(pm): re-measure the census against the merged tree Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b8419bd commit 10bd486

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

scripts/pm/dispatch-gates.mjs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,32 @@ export function reachesMetadataFormModule(path, modulePaths) {
27452745
* path each already carries is their own output, and a card editing a
27462746
* baseline matches through it today without making the gate derivable for
27472747
* anybody else.
2748+
*
2749+
* ⚠ "A literal naming their POPULATION" is the whole of that criterion,
2750+
* and one gate in this kind now fails it while READING as satisfied.
2751+
* Measured on this tree (#11199, the day PR #12300 landed): of the 2773
2752+
* tracked test files, the hint route names `check:cross-package-test-
2753+
* inputs` for 2760 of them — 99.5%, against 0–3.3% for its five siblings
2754+
* in this same kind — because #12300 taught `hintCovers` to read a glob in
2755+
* a non-final segment and the deep `packages` glob for TypeScript files
2756+
* came back to life. (That glob is not spelled here: its own wildcard
2757+
* closes a block comment.) The hint
2758+
* is neither this gate's population nor even its own literal: it is
2759+
* INHERITED from the declaration table the gate imports, where it is ONE
2760+
* package's declared turbo `inputs` glob (`@objectstack/core`'s, wide
2761+
* because a single pin test there walks the whole repo with `git
2762+
* ls-files`). It is a row the gate JUDGES, not a population the gate
2763+
* DECLARES — so it narrows the day that package's declaration narrows,
2764+
* which is the direction the gate's own repair advice pushes. And even at
2765+
* 99.5% it reaches no test file outside `packages/**` (10 tracked today,
2766+
* all under `examples/**`), none with a `.tsx` suffix (3 today, all in
2767+
* client-react), and none under `apps/**` the day one arrives — while
2768+
* the KIND reaches every one of them, because the trigger really is "a
2769+
* test file's content changed, full stop". Both routes are kept (two
2770+
* routes to one gate is redundancy, not a defect); the KIND is the
2771+
* load-bearing one. The residue and the inheritance are pinned in the
2772+
* self-test, so the next reader re-points a red case instead of
2773+
* re-deriving this paragraph.
27482774
* - i18n entry: when `check-i18n-bundles.mjs` stops discovering its targets
27492775
* at runtime and names its POPULATION in its own source — a literal each
27502776
* owning package path starts with — the path half matches and this entry
@@ -5973,6 +5999,59 @@ function selfTest() {
59735999
liveFamilies.has('check:cross-package-test-inputs'),
59746000
);
59756001

6002+
// ── The test-file entry's deletion criterion, MEASURED (#11199) ───────────
6003+
//
6004+
// The card behind these cases reported that no local derivation ever named
6005+
// `check:cross-package-test-inputs` for an edited test file. That is closed —
6006+
// the entry above has been in the table since #10542 — and the reason these
6007+
// cases exist rather than a seventh entry is what the re-measurement found:
6008+
// the entry now READS redundant against its own stated deletion criterion,
6009+
// and it is not. The full measurement is in that criterion's bullet in this
6010+
// table's docblock; what is pinned here is every load-bearing half of it, so
6011+
// the claim reddens instead of ageing.
6012+
//
6013+
// Both directions matter. The positive case keeps the redundancy honest (the
6014+
// hint route really does reach an ordinary packages test file — Zone rule:
6015+
// two routes to one gate is redundancy, never a bug, and neither may be
6016+
// deleted BECAUSE of the other). The negative cases are the residue: a class
6017+
// the hint route cannot reach in principle, with live tracked specimens.
6018+
const XPKG = 'check:cross-package-test-inputs';
6019+
const xpkgEntry = discoverFamilies().byCheck.get(XPKG);
6020+
// Live specimens, one per residue reason. If either file is ever deleted or
6021+
// renamed, re-point the case at another member of its class — and if a class
6022+
// ever EMPTIES, that is the measurement to redo, not a case to drop.
6023+
const OUTSIDE_PACKAGES = 'examples/app-crm/test/smoke.test.ts'; // not under packages/**
6024+
const TSX_TEST = 'packages/client-react/src/realtime-hooks.test.tsx'; // not *.ts
6025+
const APPS_TEST = 'apps/docs/src/x.test.ts'; // no tracked member today
6026+
t('the gate is discovered with hints at all, so these cases are not vacuous', (xpkgEntry?.hints ?? []).length > 0);
6027+
t('both residue specimens are real tracked files, so the negatives are live rather than a pair of matching strings',
6028+
existsSync(join(ROOT, OUTSIDE_PACKAGES)) && existsSync(join(ROOT, TSX_TEST)));
6029+
t('the hint route really does reach an ordinary packages test file — the redundancy #12300 recovered is real',
6030+
covers(xpkgEntry.hints, 'packages/spec/src/x.test.ts'));
6031+
t('but no hint of this gate reaches a test file outside packages/**', !covers(xpkgEntry.hints, OUTSIDE_PACKAGES));
6032+
t('nor a .tsx test file inside it', !covers(xpkgEntry.hints, TSX_TEST));
6033+
t('nor one under apps/**, the class with no tracked member to lose', !covers(xpkgEntry.hints, APPS_TEST));
6034+
// The entry itself, anchored on both sides of the rendered name the way the
6035+
// STALE cases above are: a bare substring test stays green if some other
6036+
// gate's `why` ever quotes this gate's name.
6037+
t('the KIND names the gate for every one of them — delete the entry and this reddens',
6038+
[OUTSIDE_PACKAGES, TSX_TEST, APPS_TEST].every((p) =>
6039+
changeKindLines([p], (n) => n).some((l) => l.includes(`- ${XPKG} —`))));
6040+
// The fragility half: the covering hint is INHERITED from the declaration
6041+
// table this gate imports (one package's declared turbo `inputs` glob), not
6042+
// declared by the gate as its own population. `hintOrigin` carries exactly
6043+
// that provenance, and it is what the output prints as `gate source via …`.
6044+
const xpkgCovering = xpkgEntry.hints.find((h) => hintCovers(h, 'packages/spec/src/x.test.ts'));
6045+
t('and that covering hint is inherited from a module the gate imports, not a population the gate declares',
6046+
Boolean(xpkgEntry.hintOrigin?.get(xpkgCovering)));
6047+
// The class-level claim, against the real corpus rather than two specimens:
6048+
// while ANY tracked test file is unreachable by every hint this gate has, the
6049+
// entry's deletion criterion is unmet. The day this reddens, re-measure the
6050+
// criterion and either retire the entry with these cases or re-point them.
6051+
const xpkgResidue = trackedFiles().filter((f) => isTestFilePath(f) && !covers(xpkgEntry.hints, f));
6052+
t(`the tree still holds test files no hint of this gate reaches (${xpkgResidue.length}), so the entry is not redundant`,
6053+
xpkgResidue.length > 0);
6054+
59766055
// ── The check-family coverage guard (#9187) ───────────────────────────────
59776056
//
59786057
// `docs-drift-check.yml` declared a `paths:` filter and ran a real self-test

0 commit comments

Comments
 (0)