Measured while repairing PR #10755 (the Type Check · debt ledger failure on #10269).
Not repaired there: that card's surface is one entry guard, and this is a property of
the generated re-measure project.
The measurement
remeasureProject (scripts/check-type-check-coverage.mjs) neutralises the package's
rootDironly when it has to widen include:
if(include){project.include=(unreachable.length>0 ? [...include, ...unreachable] : include).map(absolutise);if(unreachable.length>0)compilerOptions.rootDir=pkgAbs;}@objectstack/objectql has all 225 of its test files under src/, so unreachable is
empty, no widening happens, and the generated project inherits rootDir: "src" from
packages/objectql/tsconfig.json. But dropping the test globs from exclude puts
src/dry-run-hash-compat.test.ts into the program, and its line 5 imports
../scripts/dry-run-hash-compat — a file tsc then pulls in transitively, from outside
rootDir. Re-measure output, verbatim, with the dependency closure built:
packages/objectql/src/dry-run-hash-compat.test.ts(5,51): error TS6059: File
'.../packages/objectql/scripts/dry-run-hash-compat.ts' is not under 'rootDir'
'.../packages/objectql/src'. 'rootDir' is expected to contain all source files.
That line is counted, and it is inside the frozen TEST_DEBT['@objectstack/objectql']
of 355.
Why this is a finding rather than a shrug
The function's own docstring already rules on this exact diagnostic, in the branch it
does neutralise:
rootDir goes with them. It is src in most of these packages, so widening
include past it makes tsc answer with one TS6059 per added file and nothing
else [...] Under --noEmit there is no output layout for it to protect, so a
TS6059 here is a diagnostic about this generated config rather than about the
package, and counting it would be measuring the tape measure.
The reasoning does not depend on how the file entered the program. A file reached
transitively from a test is outside rootDir for exactly the same reason a file
added to include is, produces exactly the same TS6059, and is just as much a
statement about the generated config rather than about the package — but it is billed,
because the neutralisation is gated on unreachable.length > 0 rather than on the
diagnostic.
Consequences are small and entirely in the "number means what it says" direction:
- the ledgered number is one higher than the debt it names, and the entry's
note
cannot account for the extra error; - it is frozen that way, so the fix is a
--lower opportunity (355 to 354 for
objectql), never a ratchet break; - an author paying down that package's test-layer debt cannot make this one go away by
fixing code, which is the property the ratchet is supposed to have.
Not proposing the remedy here
At least three shapes exist — always set compilerOptions.rootDir = pkgAbs in the
generated project (it protects no output layout under --noEmit); drop TS6059 in
countTscErrors for the generated project only; or leave it and say so in the
docstring. Which is right depends on how many ledgered packages are in this state, and
nobody has counted: it needs a transitively-imported file outside rootDir, so it is
invisible to any scan of include globs alone. Filed so the count gets made rather
than guessed.
Dedupe
search_issues was unavailable to this seat, so all 301 open issues (PRs excluded)
were fetched through the REST list endpoint and their titles and bodies grepped for
TS6059, rootDir, remeasureProject, tape measure, re-measure, TEST_DEBT,
debt ledger and type-check-coverage. TS6059 matches only #8249 (dist-resolved
declarations) and #4311 (the framework typecheck-debt card); rootDir matches only
those and #10756. Nothing names this billing.
Related, not duplicated: #10756 (the same package's scripts/ is invisible to its own
tsc -p), #10722 (nothing reads a ledger note), #10615 and #10723 (individual
entries disagreeing with their measurement).
Generated by Claude Code
Generated by Claude Code
Measured while repairing PR #10755 (the
Type Check · debt ledgerfailure on #10269).Not repaired there: that card's surface is one entry guard, and this is a property of
the generated re-measure project.
The measurement
remeasureProject(scripts/check-type-check-coverage.mjs) neutralises the package'srootDironly when it has to wideninclude:@objectstack/objectqlhas all 225 of its test files undersrc/, sounreachableisempty, no widening happens, and the generated project inherits
rootDir: "src"frompackages/objectql/tsconfig.json. But dropping the test globs fromexcludeputssrc/dry-run-hash-compat.test.tsinto the program, and its line 5 imports../scripts/dry-run-hash-compat— a file tsc then pulls in transitively, from outsiderootDir. Re-measure output, verbatim, with the dependency closure built:That line is counted, and it is inside the frozen
TEST_DEBT['@objectstack/objectql']of 355.
Why this is a finding rather than a shrug
The function's own docstring already rules on this exact diagnostic, in the branch it
does neutralise:
The reasoning does not depend on how the file entered the program. A file reached
transitively from a test is outside
rootDirfor exactly the same reason a fileadded to
includeis, produces exactly the same TS6059, and is just as much astatement about the generated config rather than about the package — but it is billed,
because the neutralisation is gated on
unreachable.length > 0rather than on thediagnostic.
Consequences are small and entirely in the "number means what it says" direction:
notecannot account for the extra error;
--loweropportunity (355 to 354 forobjectql), never a ratchet break;
fixing code, which is the property the ratchet is supposed to have.
Not proposing the remedy here
At least three shapes exist — always set
compilerOptions.rootDir = pkgAbsin thegenerated project (it protects no output layout under
--noEmit); drop TS6059 incountTscErrorsfor the generated project only; or leave it and say so in thedocstring. Which is right depends on how many ledgered packages are in this state, and
nobody has counted: it needs a transitively-imported file outside
rootDir, so it isinvisible to any scan of
includeglobs alone. Filed so the count gets made ratherthan guessed.
Dedupe
search_issueswas unavailable to this seat, so all 301 open issues (PRs excluded)were fetched through the REST list endpoint and their titles and bodies grepped for
TS6059,rootDir,remeasureProject,tape measure,re-measure,TEST_DEBT,debt ledgerandtype-check-coverage.TS6059matches only #8249 (dist-resolveddeclarations) and #4311 (the framework typecheck-debt card);
rootDirmatches onlythose and #10756. Nothing names this billing.
Related, not duplicated: #10756 (the same package's
scripts/is invisible to its owntsc -p), #10722 (nothing reads a ledgernote), #10615 and #10723 (individualentries disagreeing with their measurement).
Generated by Claude Code
Generated by Claude Code