Skip to content

docs(typecheck): correct eighteen carriers of the stale no-tsc-program / ledger premise - #18207

Merged
claude[bot] merged 2 commits into
mainfrom
claude/issue-17715-typecheck-premise-carriers
Sep 14, 2026
Merged

claude[bot] merged 2 commits into
mainfrom
claude/issue-17715-typecheck-premise-carriers

Conversation

@claude

@claude claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #17715

Clause-②: no
This PR widens no runtime contract and changes no behaviour: every changed line is a comment. 326 of 326 added/removed lines are comment-shaped, 0 are executable.

What this is

#16742 repaired six texts that justified a placement decision with "this package has no typecheck script (DEBT ledger entry)". #17304 found a seventh in a wording its phrase key could not match. This card reported six more. My own sweep found eighteen.

The premise is false on this tree in both halves, and the corrections are written to the measurement rather than to what #16742's corrections said.

How the carriers were enumerated

The card is explicit that its list must not be inherited, so it was not. Population: 8654 tracked, non-dist, text files (the card measured 8428; the tree has moved). Each file is normalised — comment-continuation prefixes stripped, backticks and quotes removed, whitespace collapsed — and matched on the claim, never on a phrase, through three successive vocabularies:

sweep keyed on stage-1 hits
1 non-compilation / no-script / phantom / ledger-membership claims 391 files
2 a looser vocabulary hunting a wording sweep 1 could not reach 150 files
3 the carrier shape itself — an exclusion-or-absence premise followed by a consequence clause 33 package-source hits

Sweep 3 is the one that earns its place: it keys on the grammar of the claim rather than on its nouns, and it is what reached the objectql family.

Controls. Positive: all six carriers the card names appear in sweep 1 (6/6). Nonsense: a path that does not exist scores 0. And the firing control that matters here — both legacy phrase keys are now dead: git grep -F 'has no typecheck script' exits 1 with 0 matches, and so does git grep -F 'declares no typecheck script'. A zero from a phrase-keyed scan is exactly the failure mode that created this card, so every zero above is reported with the control that fired beside it.

The truth, measured per program

Program membership by tsc --listFiles, each package's build program serving as the firing control for its own test program:

package test program (tsconfig.test.json, named by typecheck) build program
@objectstack/lint 103 src test files 0
@objectstack/cli 181 files under test/ 0
@objectstack/objectql 299 src test files 0
@objectstack/plugin-approvals 42 src test files 0
@objectstack/plugin-sharing 33 src test files 0
@objectstack/driver-mongodb 30 src test files 0
@objectstack/verify 14 src test files 0
@objectstack/service-sms 5 src test files 0
nonsense control (a path that does not exist) 0 0

Ledgers re-derived inside each object literal of scripts/check-type-check-coverage.mjs (7686 lines now; the card read 7389), never over the file: DEBT holds four keys — cloud-connection, hono, observability, spec-monorepo. TEST_DEBT holds exactly one — http-conformance. Firing control @objectstack/hono = 1 in DEBT; nonsense control @objectstack/nosuchpkg = 0/0. None of the packages touched here is a member. @objectstack/cli's single TEST_DEBT occurrence is, as the card warned, a graduation note inside a comment at the head of the literal — counted, it reads as membership; read, it is the opposite.

The eighteen carriers

The card's six:

  1. packages/lint/src/runtime-gate.derived-context-keys.test.ts
  2. packages/cli/src/utils/format.exit-code.test.ts
  3. packages/cli/src/commands/validate-json-strict-exit.e2e.test.ts
  4. packages/plugins/plugin-sharing/src/exec-context-annotation.pin.ts
  5. packages/plugins/plugin-sharing/src/logger-required-warn.pin.ts
  6. packages/plugins/plugin-approvals/src/exec-context-annotation.pin.ts

Twelve the card's scan did not reach:

  1. packages/objectql/src/datasource-def-credentials-ref.pin.ts
  2. packages/objectql/src/register-object-authored-shape.pin.ts
  3. packages/objectql/src/registry-module-mock.ts
  4. packages/objectql/src/datasource-def-credentials-ref.test.ts
  5. packages/objectql/src/register-object-authored-shape.test.ts
  6. packages/services/service-sms/src/sms-manifest-providers.contract.test.ts
  7. packages/drivers/driver-memory/src/memory-driver-query-narrowing.test.ts — its claim is about the sibling driver-mongodb, which is why no scan looking at the file's own package could judge it
  8. packages/runtime/src/sandbox/quickjs-runner.test.tsthe card lists this file as a verified NON-carrier. It is both: it quote-and-corrects the premise at one site and then re-asserts it 50 lines later, grounding a pin on "DORMANT today (runtime is not typechecked — see the note above)" — where the note above says the exact opposite. A scan that reads the first claim per file and stops classifies it clean.
  9. packages/rest/src/direct-mount-introspection.test.ts
  10. packages/rest/src/rest-route-ledger.conformance.test.ts
  11. packages/rest/src/package-door-declared-code.test.ts
  12. packages/verify/src/harness.app-default-profile.test.ts

15–18 are one sub-family and are flagged as a widening for the reviewer to split if they disagree: they assert ledger content rather than non-coverage — "the pile that dominates this package's TEST_DEBT entry", "the same ceiling its TEST_DEBT entry records as TS2550 x16", "still carry that shape as measured TEST_DEBT". Zone 3 of the dispatch names "is there a DEBT ledger entry?" as part of the truth to establish, and the measured answer is no: packages/rest/test-typecheck-debt.json has entries: {}, packages/rest/tsconfig.test.json declares lib: ["ES2022"] (so the pre-es2022 ceiling is gone too), packages/verify has no test-typecheck-debt.json at all and 0 extension-less relative imports across its 14 src test files.

Conclusions, not just premises

Per the card, each carrier's conclusion was measured before any reason was rewritten. All eighteen conclusions survive; none needed its placement changed:

  • the four .pin.ts files stay .pin.ts because a .pin.ts is not a test file, so the **/*.test.ts exclusion never reached them and typecheck's unconditional first leg compiles them. That is a better reason than the one they carried, and it does not depend on anything being uncompiled.
  • packages/lint's omitted type-level witness stays omitted, now on the ground that the compiler already holds completeness at the declaration site — restating it here would be a second copy of one invariant, not a second check.
  • the two cli files stay in src/; what actually separates src/ from test/ is which leg of typecheck resolves the directive, not whether anything does.

No behaviour changed anywhere, and no package's configuration was touched — the cross-lane fence in the dispatch holds: this PR corrects prose that four lanes' packages carry and nothing else.

Verification

Gates derived with node scripts/pm/dispatch-gates.mjs --commands (no path list — it derives the change set itself: 18 paths vs merge base 99edfd008), exit codes captured to disk before any pipe.

Green: check:comment-mask-adoption (+--self-test), check:comment-mask-corpus, check-reference-carrier-shape (+--self-test), check:nul-bytes, check:type-check-coverage, check:cross-package-test-inputs, check:test-source-alias, check:doc-authoring, check:undeclared-dep-imports (+--self-test), check:tier-file-adoption.

check:type-check-debt first returned exit 3 — PREREQUISITE NOT MET, which is the gate's own code for nothing was measured, not a finding. Re-run after building the closure the way lint.yml does; the result is recorded in the report comment on the card.

Changeset

skip-changeset, measured rather than defaulted. Every affected package declares files: ["dist", "README.md", "CHANGELOG.md"]; this diff touches no dist, no README and no CHANGELOG, and its 326 changed lines are 326 comments and 0 executable statements, so no published byte can move. The classifier's firing control: fed real code lines (import ..., const x = 1;) it declines to call them comments.

Acceptance notes

Noted, not filed — observations, with the seat that would carry them:

  • The class cannot be held closed by any prose scan, and this PR is the third proof of it. [finding] Six test-file headers justify a pin's placement with "this package has no typecheck script (DEBT ledger entry)" — false for all three packages named; the DEBT ledger holds four other packages entirely #16742 keyed on a phrase, [finding] A FIFTH carrier of #16742's false typecheck-script premise, in a wording #16742's scan cannot match — rest-api-plugin-slot-lookups.test.ts says NO tsc program compiles it #17304 keyed on a second phrase, this card keyed on the claim — and the claim-keyed scan still missed twelve, in two further wordings, plus one file it read as clean because it stopped at that file's first claim. A fourth sweep will find a fifth wording. ⛔ Not built here; it is neither small nor in scope. The shape that would work inverts the problem: stop letting prose carry the fact. A placement that depends on program membership should cite a machine-checked declaration instead of a sentence — a one-token annotation on the file (which program is expected to read it) that a gate reconciles against tsc --listFiles, red when they disagree. check:type-check-coverage already computes exactly that membership for its PINS_CHECKED invariant, so the reconciliation is nearly free; the missing half is the annotation. Carrier: domain:devx, alongside the existing PINS_CHECKED family.
  • Two scanning lessons, both cheap and both general. (a) A file can be BOTH a corrected non-carrier and a live carrier — classify per claim occurrence, never per file. (b) A claim can be about a sibling package; a sweep that checks each hit against its own package's truth cannot judge those at all.
  • packages/lint, @objectstack/rest and @objectstack/verify each carry a test layer at zero with no ledger, which is the intended steady state and worth leaving visible in the prose — the corrections say so where the old text implied a ratchet to hide behind.
  • The generated _comment field of every test-typecheck-debt.json restates the same premise in the past tense ("which tsconfig.json excludes and therefore no gate ever read"). It is past-tense and therefore not a carrier, and it is generator-owned — a hand edit is gone at the next regeneration. Left alone deliberately. Carrier: whoever next touches scripts/check-test-typecheck.mts.

Generated by Claude Code

…mise

The six docblocks the card names each ground a placement decision on
"no tsc program compiles this file / reads that directory", or on a
DEBT/TEST_DEBT entry in scripts/check-type-check-coverage.mjs. Both
halves are false on this tree and are corrected to the measurement
rather than deleted, because the wrong sentence is the one a sibling
package copies.

Measured with `tsc --listFiles` per program, with a firing control (the
build program, 0 test files) and a nonsense control (a path that does
not exist, 0 in both):

  @objectstack/lint             tsconfig.test.json  103 src test files
  @objectstack/cli              tsconfig.test.json  181 files under test/
  @objectstack/plugin-sharing   tsconfig.test.json   33 src test files
  @objectstack/plugin-approvals tsconfig.test.json   42 src test files

Ledger membership re-derived INSIDE each object literal of
scripts/check-type-check-coverage.mjs, not over the file: DEBT holds
four keys (cloud-connection, hono, observability, spec-monorepo) and
TEST_DEBT exactly one (http-conformance). None of the four packages
above is a member; @objectstack/cli's single TEST_DEBT occurrence is a
graduation note in a comment at the head of the literal.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
…not reach

My own claim-keyed sweep over the tracked tree (8654 text files) reached
the card's six and twelve more it did not, in two wordings its keys
could not match plus one file it had cleared as a verified non-carrier.

Same premise, corrected to the measurement per package:

  objectql x5   "excluded from every tsc program the typecheck script
                runs" / "type-checked by no program the typecheck script
                runs" -- tsconfig.test.json puts 299 src test files in a
                program `typecheck` names (build program: 0)
  service-sms   claims a TEST_DEBT entry in check-type-check-coverage.mjs
                and that a type-level check here is evaluated by nothing;
                no such key, and the file is in the test program
  driver-memory claims the identical pin in driver-mongodb would be a
                phantom check; that package's tsconfig.test.json puts 30
                src test files in a program its typecheck names
  runtime       quickjs-runner.test.ts corrects the premise at one site
                and re-asserts it 50 lines later ("DORMANT today -- runtime
                is not typechecked"); the file contradicted itself
  rest x3       cite a TEST_DEBT entry recording TS7006/TS2550 piles and a
                pre-es2022 lib ceiling; entries is {}, lib is ES2022, and
                the package holds no key in either ledger literal
  verify        cites older test files carrying extension-less imports "as
                measured TEST_DEBT"; 0 such imports across its 14 src test
                files and no test-typecheck-debt.json exists

Every zero above carries a firing control (the build program for the same
package) and a nonsense control (a path that does not exist).

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 6 changed file(s) yielded no anchor (packages/objectql/src/datasource-def-credentials-ref.pin.ts, packages/objectql/src/register-object-authored-shape.pin.ts, packages/objectql/src/registry-module-mock.ts, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 3 changed package(s)).

What this run could not see
  • 6 changed file(s) yielded no anchor (packages/objectql/src/datasource-def-credentials-ref.pin.ts, packages/objectql/src/register-object-authored-shape.pin.ts, packages/objectql/src/registry-module-mock.ts, …) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json d4554d4f5aef6f767de187da29e2d9f583da2543packageMentionDocs.

@github-actions github-actions Bot added the tests label Sep 14, 2026
@claude
claude Bot marked this pull request as ready for review September 14, 2026 15:58
@claude
claude Bot enabled auto-merge September 14, 2026 15:58
@claude
claude Bot added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit fbeb6d6 Sep 14, 2026
40 checks passed
@claude
claude Bot deleted the claude/issue-17715-typecheck-premise-carriers branch September 14, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

1 participant