fix(scripts): SOURCES_COVERED asks every package, ledgered or not - #15482
Merged
baozhoutao merged 3 commits intoSep 4, 2026
Conversation
`check:type-check-coverage` evaluated its SOURCES_COVERED clause only for a package that DECLARES a `typecheck` script. The argument written beside that scope was that a DEBT package's answer is already "nothing reads this package", which its ledger owns. It is not: a DEBT row records an ERROR COUNT taken through `tsc -p tsconfig.json`, so a source directory OUTSIDE that program is in neither the count nor any other reading. `packages/core/examples` held 2 non-test source files in no tsc program at all, neither of which had ever compiled, and they surfaced only when an unrelated PR added a `typecheck` script — repairing them moved the package 12 -> 29 errors, all of it drift accumulated while nothing could check the file. The clause now runs over `accountedPrograms()`, the same set TESTS_COVERED is decided against: the configs the `typecheck` script invokes, or `tsconfig.json` for a package with no such script (what `measureDebt` runs). The finding names the claim it falsifies — a `typecheck` script, a DEBT row, an EXEMPT row, or nothing accounting for the package at all — rather than assuming a script the package may not have. Measured on this tree: the gate stays green (75/79 covered, 4 in DEBT, 1 exempt), so no ledger row and no exclusion was widened to keep it green. Two legs: with a source file planted in a DEBT package's unread directory the old gate exits 0 and the new one reports it. Also adds the gate's report on its own scope. Three axes of this gate's blindness have each been found by a person tripping over one, and the shape they share is a clause skipped for a population with the run saying so nowhere. `SCOPED_CLAUSES` declares every such scope beside its predicate and its reason, and every green run prints who was left out of what — today that is GENERATED_COVERED over the 4 packages declaring no `typecheck` script. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…pe-check-coverage-sources-clause
`clauseScopeLine` is computed over the enumerated workspace packages, and the workspace ROOT is not one of them: `observed()` builds the root from its manifest alone, with none of the four observation fields, so TESTS_COVERED, SOURCES_COVERED, PINS_CHECKED and GENERATED_COVERED are never asked of it while this file's header says the root is included "like any other package's". Filed as #15483 (latent today: the root tsconfig declares no `include`, and the tree has 0 root-level test files). A self-report that inherited that boundary silently would be the defect it reports on, so the line says it. Pinned in both branches of the existing self-test cases rather than as new ones, so the battery floor is unmoved. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Contributor
Author
|
ACCEPT — PM seat Reviewed against the three-dot diff
Generated by Claude Code |
baozhoutao
marked this pull request as ready for review
September 4, 2026 18:01
baozhoutao
enabled auto-merge
September 4, 2026 18:01
baozhoutao
deleted the
claude/issue-14918-type-check-coverage-sources-clause
branch
September 4, 2026 18:40
This was referenced Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14918
check:type-check-coverageevaluated itsSOURCES_COVEREDclause only for a package that DECLARES atypecheckscript. The scope was deliberate and its argument was written beside it — "a DEBT package's answer is already 'nothing reads this package', which its own ledger owns; asking again here would bill the same hole to two ledgers". That argument does not survive contact with what a DEBT row is: the row records an error count, taken throughtsc -p tsconfig.json, so a source directory outside that program is in neither the count nor any other reading anybody performs.This is the third axis of the same gate, and the card is explicit that a fix must claim only one: #14630 (needs a pre-existing ledger row to notice a package at all) and #14386 (package-ROOT source, depth 0) both landed already and are not touched here.
The repair
SOURCES_COVEREDis now asked of every workspace package, overaccountedPrograms()— the same setTESTS_COVEREDhas been decided against since #7353: the configs thetypecheckscript invokes, or, for a package with no such script,tsconfig.json, which is whatmeasureDebtruns. The clause's file-level predicate, itsdepth > 0scope andROOT_SOURCE_FILESare untouched.The finding now names the claim it falsifies instead of assuming that claim is a
typecheckscript:typecheckDEBTtsconfig.jsonEXEMPTtsconfig.json⛔ No ledger row was added and no exclusion was widened.
UNCHECKED_SOURCE_DEBTis still empty and still closed.The gate's report on its own scope
The card's own observation is that each of the three axes was found by a person tripping over it, never by an instrument — and the shape they share is not "the gate was wrong": a clause was skipped for a population, deliberately, and the run said so nowhere. A green line naming 79 packages reads as 79 packages checked.
SCOPED_CLAUSESnow declares every per-package clause that is asked of a subset, beside its predicate and the argument for why that subset is legitimate, and every green run prints who was left out of what. Today exactly one clause is scoped:The line names the population it cannot speak for
clauseScopeLineis computed over the enumerated workspace packages, and the workspace root is not one of them:observed()builds the root from its manifest alone, with none of the four observation fields, soTESTS_COVERED,SOURCES_COVERED,PINS_CHECKEDandGENERATED_COVEREDare never asked of it — while this file's header says the root is included "like any other package's". Found while writing the line; filed as #15483 (latent today: the root tsconfig declares noinclude, andgit ls-filesfinds 0 root-level test files), and not repaired here — it is a fourth axis and this card is explicit that a fix must claim only one. The line says so rather than inheriting the boundary silently, which would be the defect it reports on:Measured readings
Re-derived at claim time — triage's last reading (70/79, 9 ledgered, after PR #14916) is stale: the ledger is down to 4.
origin/main@0db29473c)SOURCES_COVEREDwas asked of⇒ The gate stays green on this tree: the 3 non-root DEBT packages and the 1 EXEMPT package have no unread source directory today. Nothing had to be papered over, and there is no
needs_decisionhiding behind this green.Two legs, so the green above is not read as "the clause does nothing"
A
.tsfile planted inpackages/cloud-connection/scripts/(a DEBT package, notypecheckscript), same tree, same commit:EXIT=1,packages/cloud-connection/scripts: 1 non-test source file(s) here sit outside every tsc program that accounts for @objectstack/cloud-connection -- it declares no typecheck script, so tsconfig.json is all that reads it, and its DEBT entry records the ERROR COUNT tsc reports through that programEXIT=0,check-type-check-coverage: OK — 75/79 workspace packages type-checkedBoth mutations were confirmed on disk by grepping for the injected and the removed text (
mutation_present=1 original_gone=0), and every restore was verified against theHEADblob hash (780118dd1f5638c6a996233300bc47e240935c37) withgit diff HEADempty.Two more ablations, on the self-test rather than the tree:
skippedClauses()neutered toreturn []→ self-testEXIT=1, 2 failures (skippedClauses — the packages a scoped clause was not asked of are named: expected [...], got []).EXIT=1, 3 failures, one per new ledger-basis case.Verification
Exit codes captured before any pipe; each verdict line is the gate's own.
The self-test grew by 3 semantic cases and 6 observation cases;
SELF_TEST_BATTERIESwas re-floored (observation cases57 → 63) and the three prose figures that quote it were moved with it. The row this change inverts —a DEBT package is not also billed for unread source— was replaced, not deleted: it asserted the behaviour this card calls the defect.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 26 commands from the real change set (scripts/check-type-check-coverage.mjs, three-dot against the merge base). All 26 were run: 25 EXIT=0.pnpm check:type-check-debt(the--re-measurevariant), is NOT MEASURED, not a pass and not a red:EXIT=3,check-type-check-coverage: PREREQUISITE NOT MET — --re-measure cannot run: 33 workspace dependenc(ies) of the ledgered packages have no built type entry point on disk. That is a property of a fresh worktree, not of this diff —origin/main's own copy of the script, run on this same tree, refuses identically withEXIT=3. CI builds the closure (turbo run build --filter='./packages/*') before that step.Every command above ran on this branch's final commit
a103ce24f(git rev-parse --short HEAD, tree clean), andpnpm lint— the repo-wideeslint . --no-inline-config— was run in full rather than narrowed: EXIT=0.All figures above were measured on a shared box under the repo's verify lock, which excludes other locked runs and nothing else.
🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code