diff --git a/packages/verify/tsconfig.test.json b/packages/verify/tsconfig.test.json index 25bb5b40307..73c531db2bb 100644 --- a/packages/verify/tsconfig.test.json +++ b/packages/verify/tsconfig.test.json @@ -14,20 +14,28 @@ // line and not a probe that sees nothing. The same probe against THIS config, // on that same tree, names 10 of 10 (981 program files -> 990). // -// ⚠️ ROUTE (b) WAS AVAILABLE HERE AND WAS NOT TAKEN, which is worth recording -// because `check-type-check-coverage.mjs` tells the next reader to assume it is -// not: dropping `**/*.test.ts` from `tsconfig.json`'s `exclude` leaves -// `pnpm check:type-source-resolution` GREEN for this package (measured under a -// trap-restored mutation at 1d67130585 -- exit 0, 124 programs across 78 -// packages), unlike the 14 of 18 entries that gate reports as red. It was -// declined on module semantics, not on availability: vitest executes these +// ⚠️ THE OTHER EDIT -- dropping `**/*.test.ts` from `tsconfig.json`'s +// `exclude` -- WAS AVAILABLE HERE AND WAS NOT TAKEN, and the reason is worth +// recording because it is not the reason the gate's prescription now gives. It +// was declined on module semantics, not on availability: vitest executes these // files through vite, which resolves extension-less relative specifiers, while // `tsconfig.json` inherits `NodeNext` from the repo root and demands `.js` on -// every one of them. Route (b) would hold the test layer to a resolver that +// every one of them. That edit would hold the test layer to a resolver that // never runs it -- the same config-tier noise the shared gate's header // attributes 108 of spec's 842 raw errors to. Matching vitest is fidelity, not // laxity, and it is why 28 of the 30 sibling configs override these two keys. // +// ⛔ Availability was never the question here, and it is nobody's question any +// more: measured under a trap-restored mutation at 1d67130585, dropping that +// exclusion left `pnpm check:type-source-resolution` GREEN for this package +// (exit 0, 124 programs across 78 packages), unlike the 14 of 18 entries that +// gate reported as red. That gate was retired (2026-09-18, #18373), and +// `check-type-check-coverage.mjs` no longer offers the exclusion edit as a +// route at all -- withdrawn under the maintainer ruling of 2026-09-18 on +// #18953, so the sibling config is the only route it prescribes. ⛔ Read the +// green above as a reading taken on one tree, never as a standing clearance, +// and ⛔ read the gate's silence as neither. +// // ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`, `noUnusedParameters`, // `noImplicitReturns`, `esModuleInterop` and the rest are inherited from // `tsconfig.json` (and through it from the repo root). `rootDir: ".."` and the diff --git a/scripts/check-type-check-coverage.mjs b/scripts/check-type-check-coverage.mjs index 9f550119a0f..0172bd0836f 100644 --- a/scripts/check-type-check-coverage.mjs +++ b/scripts/check-type-check-coverage.mjs @@ -937,9 +937,12 @@ const EXEMPT = { // So it took the #5286 sibling route (`tsconfig.test.json` named by the // `typecheck` script), which puts the same 10 files in front of tsc while // leaving `tsconfig.json` -- the only config that gate reads -- untouched. The -// general lesson, which is this ledger's to carry: the two remedies are +// general lesson, which is this ledger's to carry: the two edits were // interchangeable only where the excluded tests import nothing the src layer -// does not, and that is a property to MEASURE per package, never to assume. +// does not, and that was a property to MEASURE per package, never to assume. +// ⛔ Nobody has to weigh them any more -- the exclusion edit is no longer an +// offered route (#18953); the sibling config is the whole prescription, and +// this paragraph is the record of why, not a second option. // // `@objectstack/rest` GRADUATED from this ledger (#12542; entry: 155 raw, // re-measured 37 raw across 13 files under the sibling program). It is worth a @@ -987,10 +990,13 @@ const EXEMPT = { // an exclusion go red the way trigger-record-change did, 4 stay green // (`objectql`, `lint`, `formula`, `verify`), and the 19th (`cli`) has no // exclusion to drop at all -- its tests are hidden by an `include` that never -// reaches them. So that package was the majority case, not the exception, and -// the graduation message no longer offers the exclusion route without its -// precondition. Re-measure before relying on the split: it moves with every -// import a test file gains. +// reaches them. So that package was the majority case, not the exception -- +// and that is the measurement the graduation message was withdrawn on: it no +// longer offers the exclusion route AT ALL (maintainer ruling of 2026-09-18 on +// #18953), once the gate that decided the precondition had itself been retired +// (#18373). ⛔ The 14/4 split above is kept here as a READING, never as a route +// to pick from: it was taken at e47d5ef61, it moves with every import a test +// file gains, and nothing measures it any more. // // ── #14062: three plugin entries GRADUATED, and what replaced them ─────────── // @@ -1094,14 +1100,16 @@ const EXEMPT = { // what WOULD happen, not about an existing dead pin, exactly as `cli`'s // graduation recorded for its own 115 files. // -// ⚠️ ROUTE (b) WAS AVAILABLE HERE and was still not taken. The #11491 note -// above names `verify` as one of the 4 entries whose exclusion could be dropped -// with `check:type-source-resolution` staying green, and that split was -// re-measured on 2026-09-04 under a trap-restored mutation and still holds for -// this package (exit 0; 124 programs across 78 packages). It was declined on -// module semantics: `tsconfig.json` inherits NodeNext from the repo root and -// would hold the test layer to a resolver vitest never runs it under. Onboard -// by WIRING, not by widening the build config. +// ⚠️ DROPPING THE EXCLUSION WAS AVAILABLE HERE and was still not taken. The +// #11491 note above names `verify` as one of the 4 entries whose exclusion +// could be dropped with `check:type-source-resolution` staying green, and that +// split was re-measured on 2026-09-04 under a trap-restored mutation and still +// held for this package (exit 0; 124 programs across 78 packages). It was +// declined on module semantics: `tsconfig.json` inherits NodeNext from the repo +// root and would hold the test layer to a resolver vitest never runs it under. +// Onboard by WIRING, not by widening the build config -- which is now the only +// route the graduation message prescribes at all (#18953), so this record is +// history and ⛔ not a second option anybody still has to weigh. const TEST_DEBT = { // ── #14710: `@objectstack/cli` GRADUATED, and it was not paid down ───────── // @@ -4482,11 +4490,32 @@ function ratchetRemedyCarriesAuthority(message) { // // So the fix is not more words. It is the branch: `m.ledger` is already on // every measurement, and each ledger's remedy prints only where it is the -// remedy. Neither is dropped -- both are still offered, in the branch that -// owns them. Within TEST_DEBT there IS a real choice of route, so that one -// keeps both and names the PRECONDITION plus the command that decides it: a -// message the reader has to open a gate's source to act on has not fixed -// anything. +// remedy. Neither LEDGER is dropped -- each still gets the remedy that is its +// own, in the branch that owns it. +// +// ── Within TEST_DEBT the exclusion route came OUT (#18953) ────────────────── +// +// TEST_DEBT used to print a SECOND route beside the sibling config: drop the +// `**/*.test.ts` entry from `exclude` (or widen `include` to reach the test +// tree). Whether that route was available for a given package was decided by +// `check:type-source-resolution` -- and that gate was RETIRED under the +// maintainer ruling of 2026-09-18 on #18373, leaving an official route whose +// precondition nothing measured any more. What it had measured is the second +// bullet above: RED for 14 of the 18 entries that had an exclusion to drop. A +// remedy that is wrong 14 times out of 18, with nothing left to say so, is not +// a remedy, so the maintainer ruling of 2026-09-18 on #18953 (decision batch +// #159 item 4, letter ②, maintainer verbatim 「同意」) withdrew it: the printed +// prescription names (a) alone, and the docs that restated the route drop it +// with the same edit. +// +// ⛔ The other way out was REJECTED in that same ruling, so the way back in is +// closed from both sides: having THIS gate measure the precondition itself +// rebuilds half of a gate the maintainer had just retired. An author who +// widens `include` to the test tree anyway does so on their own judgement -- +// ⛔ not on this gate's advice, which now says nothing about that edit in +// either direction. The self-test pins the withdrawal as ANTI-content, the way +// every other branch here is pinned, because the state a well-meaning re-merge +// returns to is the one that printed both. // // ⛔ This changes no verdict and no number. Graduation candidates were, and // remain, a NOTE -- never a failure. @@ -4511,16 +4540,9 @@ function graduationRemedy({ ledger, isRoot = false }) { `Onboard it: put the hidden test files in front of tsc, and delete the TEST_DEBT entry in the same ` + `PR. ⛔ Adding a \`typecheck\` script is NOT the remedy here -- this ledger is "src checks, tests ` + `are hidden", so the package already has one.\n` + - ` (a) The #5286 sibling route: add a \`tsconfig.test.json\` that reaches the ` + - `tests and NAME it in the \`typecheck\` script. Always available -- it leaves \`tsconfig.json\` alone.\n` + - ` (b) Drop the \`**/*.test.ts\` entry from \`exclude\` in \`tsconfig.json\` (or widen \`include\` to ` + - `reach the test tree). ⛔ The gate that DECIDED whether this route was available, ` + - `\`check:type-source-resolution\`, was RETIRED under the maintainer ruling of 2026-09-18 on #18373 ` + - `-- so nothing measures it for you any more, and ⛔ its silence is not a clearance. What it measured ` + - `has not changed: the re-admitted tests import workspace packages this package's src program never ` + - `held, its registry was ⛔ SHRINK-ONLY so registering the new ones was never the way out, and it read ` + - `red on 14 of the 18 entries that have an exclusion to drop. Treat (b) as the worse route and prefer ` + - `(a), which leaves \`tsconfig.json\` alone; nothing in this gate's own verdict will tell you.` + ` (a) The #5286 sibling route, and the ONLY route this gate prescribes: add a ` + + `\`tsconfig.test.json\` that reaches the tests and NAME it in the \`typecheck\` script. Always ` + + `available -- it leaves \`tsconfig.json\` alone.` ); } if (ledger === 'DEBT') { @@ -6405,15 +6427,17 @@ function selfTest() { + 'that remedy is a no-op on every one of them -- the misfire #11491 was filed on.', }, { - label: 'TEST_DEBT graduation still carries what the retired gate measured about the exclusion route', + label: 'TEST_DEBT graduation prescribes the sibling config ALONE -- the exclusion route is withdrawn', message: testDebtGrad, - present: ['check:type-source-resolution', 'SHRINK-ONLY', 'tsconfig.test.json'], - absent: [], - why: 'the exclusion route read red on 14 of the 18 entries that have an exclusion, and this gate ' - + 'never ran it. A message the author has to read a second gate\'s SOURCE to act on is the half ' - + 'of #11491 that a correct-but-terse rewrite would leave unfixed -- and once that gate was ' - + 'retired (2026-09-18, #18373) the measurement is the ONLY thing left warning the author, so ' - + 'these needles stay exactly as they were.', + present: ['tsconfig.test.json', 'the ONLY route this gate prescribes'], + absent: ['exclude', 'widen', 'check:type-source-resolution', 'SHRINK-ONLY'], + why: 'the exclusion route read red on 14 of the 18 entries that had an exclusion, and the gate that ' + + 'decided the precondition per package was retired (2026-09-18, #18373), so nothing measured it. ' + + 'The maintainer ruling of 2026-09-18 on #18953 withdrew the route rather than leave an official ' + + 'path that is wrong 14 times out of 18: the remedy names (a) alone. These are ANTI-content ' + + 'needles on purpose -- a presence-only assertion would sit green through exactly the ' + + 're-merge that hands the route back, and the retired gate\'s NAME is only one of the spellings ' + + 'it could come back under, which is why `exclude` and `widen` are named beside it.', }, { label: 'the workspace root graduates through `typecheck:root`, never through `typecheck`', @@ -6428,9 +6452,12 @@ function selfTest() { label: 'an unrecognised ledger inherits NEITHER remedy', message: gradNote({ ledger: 'FUTURE_DEBT' }), present: ['FUTURE_DEBT'], - absent: [ADD_SCRIPT, 'drop the test exclusion', 'check:type-source-resolution'], + absent: [ADD_SCRIPT, 'drop the test exclusion', 'tsconfig.test.json'], why: 'a third ledger silently receiving DEBT\'s advice is how this message was wrong for TEST_DEBT ' - + 'for its whole life. Saying less is the only safe default.', + + 'for its whole life. Saying less is the only safe default. ⚠️ The TEST_DEBT needle here is ' + + '`tsconfig.test.json` and NOT the retired gate\'s name: that name left the message when #18953 ' + + 'withdrew the exclusion route, and an anti-content needle naming a string no branch can emit ' + + 'proves nothing about inheritance.', }, ]; for (const c of gradCases) { @@ -6442,8 +6469,8 @@ function selfTest() { for (const needle of c.absent) { if (c.message.includes(needle)) failures.push( - `#11491 graduation remedy — ${c.label}: message STILL contains ${needle}, which is the other ` - + `ledger's remedy. ${c.why}`, + `#11491 graduation remedy — ${c.label}: message STILL contains ${needle}, which this case pins ` + + `as ABSENT -- another ledger's remedy, or a route this one no longer offers. ${c.why}`, ); } }