Skip to content

Commit 0f81717

Browse files
committed
docs(check-type-source-resolution): name the paths precondition and the closure at the point of refusal
The refusal names `paths` first. That remedy has a precondition it never stated: the consuming program's `rootDir` has to contain the dependency's source. Where it does not, tsc admits the dep's file graph and then reports TS6059 for all of it, billed to the consuming package's test-typecheck ledger — the PR #12570 shape, reached from the `paths` limb instead of the re-baseline one. Both the ledger and `rootDir` are maintainer-only, so at that point the author has no self-serve remedy and the message named none. The knowledge was already in this file — the header's with-`paths` red and the PR #12570 reading over the registry — and nowhere in the text an author reads. Written as a CONDITION, never a blanket closure: `paths` stays correct wherever the program's `rootDir` does contain the source, and a message overstating the closure would be worse than the current silence. The refusing sentence, the ⛔ SHRINK-ONLY testimony and the ONBOARDED exception are untouched, so `check-ratchet-remedy-authority` still classifies this gate as `refused`. Two self-test pins added for the new halves and the battery floor raised 10 -> 12 to match. Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8 Co-authored-by: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 1ebde49 commit 0f81717

1 file changed

Lines changed: 46 additions & 2 deletions

File tree

scripts/check-type-source-resolution.mjs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ const SELF_TEST_BATTERIES = Object.freeze({
186186
'false positives': 3,
187187
'fail-closed': 2,
188188
'#11490: the population is per PROGRAM': 6,
189-
'the registry, audited in BOTH directions': 10,
189+
'the registry, audited in BOTH directions': 12,
190190
'census guard: sibling-config discovery going quiet is INVISIBLE': 14,
191191
'the import clause is bounded to ONE statement (#12555)': 8,
192192
'the declaration must still BE the workspace (#11510)': 22,
@@ -1650,7 +1650,29 @@ function check(root, registry) {
16501650
' then the program set itself moved, which since #11490 a package can do, and `paths` is\n' +
16511651
' measured to be the wrong tool for it: on PR #12570 it billed source diagnostics from\n' +
16521652
' other packages into this ledger. That case is a re-baseline, and it is\n' +
1653-
' settled by the doc-block over the registry, not by this message. Read it first.',
1653+
' settled by the doc-block over the registry, not by this message. Read it first.\n' +
1654+
// #16000: the `paths` limb is the FIRST remedy this message names, and for a consuming
1655+
// program whose `rootDir` excludes the dependency's source it is closed too — so an author
1656+
// reading this straight through walks into a SECOND wall nothing here mentioned. The
1657+
// knowledge was in this file the whole time (the header's with-`paths` red, and the PR
1658+
// #12570 reading over the registry) and nowhere in the text the author reads; the #15978
1659+
// round paid a full cycle for that gap, which is what #16000 records.
1660+
//
1661+
// ⚠️ Written as a CONDITION and never as a blanket closure. `paths` remains the correct
1662+
// remedy wherever the consuming program's `rootDir` DOES contain the dependency's source,
1663+
// and a message overstating the closure would turn an author away from a route that is
1664+
// open — worse than today's silence. The condition is what was measured, not the verdict.
1665+
' ⚠️ And `paths` is not always available — check its precondition before you take that\n' +
1666+
' route. It puts the dependency\'s SOURCE into this program, so every file it pulls in has\n' +
1667+
' to sit under the consuming program\'s `rootDir`. Where that `rootDir` excludes the\n' +
1668+
' dependency (a package-local `./src`, whose `tsconfig*.json` header may say in so many\n' +
1669+
' words that it will not widen), tsc admits those files and then reports TS6059 "is not\n' +
1670+
' under rootDir" for that package\'s whole file graph — billed to THIS package\'s\n' +
1671+
' test-typecheck ledger, which the package that owns the source cannot see. That is the\n' +
1672+
' PR #12570 shape again, reached from the `paths` limb instead of the re-baseline one.\n' +
1673+
' ⛔ In that case no self-serve remedy is left, and the honest move is to NOT take the\n' +
1674+
' dependency: reach the subject through in-package source, or escalate. ⛔ Never widen\n' +
1675+
' that ledger and ⛔ never widen a `rootDir` to make room — both are maintainer-only.',
16541676
);
16551677
if (gone.length > 0)
16561678
failures.push(
@@ -2231,6 +2253,28 @@ function selfTest() {
22312253
+ 'the program set itself, which #11490 made possible and 14 queued onboardings each arrive at',
22322254
);
22332255

2256+
// #16000. `paths` is the FIRST remedy this message names, and it has a
2257+
// precondition the message did not state: the consuming program's `rootDir`
2258+
// must contain the dependency's source. Where it does not, that route ends in
2259+
// TS6059 billed to a ledger the owning package cannot see — measured by the
2260+
// #15978 round, which spent a full cycle discovering it, and re-measured in the
2261+
// PR for this card. Two pins, because the halves fail independently: the
2262+
// DIAGNOSTIC an author meets on that route, and the fact that what would clear
2263+
// it is not a dev seat's to take — a message naming neither recommends a route
2264+
// and then names no remaining self-serve option when it closes.
2265+
expect(
2266+
has(grown.failures, 'TS6059'),
2267+
'the failure text no longer names the diagnostic the `paths` remedy produces when the consuming '
2268+
+ "program's `rootDir` excludes the dependency's source — the message then recommends a route "
2269+
+ 'whose second wall is silent from here, which is the cycle #16000 recorded',
2270+
);
2271+
expect(
2272+
has(grown.failures, 'maintainer-only'),
2273+
'the failure text no longer says that the routes past that wall are closed to a dev seat — '
2274+
+ 'without it this message names `paths` first and names NO remaining self-serve option for '
2275+
+ 'the case where `paths` is unavailable, which is the whole of #16000',
2276+
);
2277+
22342278
const wide = check(root, { ...measuredNames, '@fx/violator': ['@fx/spec', '@fx/other', '@fx/gone'] });
22352279
expect(has(wide.failures, 'STALE'), 'a registry entry listing a dep that is no longer dist-resolved did not fail');
22362280

0 commit comments

Comments
 (0)