Skip to content

Commit b253fad

Browse files
docs(devx): re-anchor the dead tracker citation in check-test-typecheck and regenerate the 19 test-typecheck ledgers (#21010)
Fixes #20715 Clause-②: no ## What changed The shared test-typecheck gate wrote a tracker number that answers 404 (`#13470`) into the generated `_comment` of every package's `test-typecheck-debt.json`. This PR re-anchors it at the producer, `scripts/check-test-typecheck.mts`, and regenerates every copy with its own package's `gen:test-typecheck-debt`. - **The `_comment` literal (`LEDGER_COMMENT`)** now says the lesson in words (ruling C+D's form D, no number): entries are per-signature "never to a bare total, because a total can hold while the errors underneath it are replaced wholesale". The fragment the gate pins by arrival, `never to a bare total`, is unchanged. - **The other 23 lines of the producer that cite the same number** are re-anchored too, because the card's re-check names the whole file and answers 0 only when they are gone. Comment prose (6 sites) now cites commit `57827b617` (form C). Strings the author sees or the self-test prints (17 sites: 6 battery names and `battery()` calls, 10 assertion labels, the success line) say the lesson without a number (form D). Nothing else on those lines moved. - **19 ledgers regenerated**, one `gen:test-typecheck-debt` per package, never by hand. In each, one line moved: `_comment`. - **`packages/rest/test-typecheck-debt.json` also has its authored `_note` re-anchored by hand** (`#13470` became `commit 57827b6`). The generator never writes `_note` and preserves it verbatim, so no regeneration could reach it, and the card's re-check covers it. 20 files, 45 insertions and 44 deletions against base `05be35259`: the producer, plus one line in each of 19 ledgers (two in rest). ## Measured before building - **The premise holds, and the card's count was short.** `GET /repos//issues/13470` answers 404 (2026-10-01); #5286, #12624 and the other numbers in the same `_comment` answer 200. At base `05be35259` the card's re-check answers **44 lines**: 20 in the 19 ledgers (rest carries one in `_comment` and one in `_note`) and **24 in the producer**, not one. - **H1, what regeneration costs and moves.** Regeneration re-measures each package's test errors, so it needed the dependency closure built: 59 turbo build tasks, 6m46s under the shared lock. After it, `--update` rewrote **only `_comment`** in all 19, and **no debt moved**: `entries`, key order and `_note` are byte-equal to base in every ledger (165 files, 1233 errors, 362 distinct signatures across the 19; every package's own count unchanged). No ledger was left unregenerated. - **H2, whether the gate reads `_comment`.** It does not. `check:test-typecheck` judges `loadLedger().entries` alone, and nothing else reads a ledger's `_comment`. Mutation proof on `packages/rest`: with `_comment` set to a marker string, `pnpm --filter @objectstack/rest check:test-typecheck` still exits 0 (OK line printed); restored from `HEAD`, `git diff HEAD` empty. So a producer edit without regeneration would not red anything; the regeneration is what makes the 19 copies true. - **H3, the anchor.** `57827b617` ("pin test-typecheck debt by error IDENTITY, not per-file count") is the commit that decided per-signature entries; its message records the packages/rest ablation the number stood for. The repository history is deep enough: the commit is present, and `git log` on the producer lists it among 7 commits. ## Proof - **Each regenerated copy changes only its `_comment` line.** A script compared every ledger at `HEAD~1` with the working copy: same keys and key order, `entries` byte-equal, `_note` equal, exactly one changed line, and the new `_comment` is the old one with exactly one clause replaced. Result: `ALL 19 carriers: only the _comment line moved`. Against base `05be35259` the same script reports one difference, rest, which changes two lines (`_comment` and the authored `_note`), as stated above. - **Re-check.** `git grep -n "#13470" -- '*/test-typecheck-debt.json' scripts/check-test-typecheck.mts` answers 0 (exit 1). Positive control, same pathspec at the base commit: `git grep -c "#13470" 05be352 -- ...` lists 20 files (19 ledgers plus the producer). - **Self-test.** `tsx scripts/check-test-typecheck.mts --self-test` exits 0 at the final head; the renamed batteries still register against the roster floor, so no battery went unattributed. - **Spot checks of the check mode** against the regenerated ledgers at the final head: rest, spec (52 files, 248 errors, 136 signatures) and runtime (27 files, 190 errors, 68 signatures) each print `check:test-typecheck: OK`. ## Gates (head `f9b496b88`) `dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` over the actual diff derives 74 commands. All 74 ran, each exit recorded before any pipe, and `--ran` reconciles: `74 derived, 74 run, 0 NOT-MEASURED, 0 UNRUN`. All 74 exited 0, including `pnpm check:type-check-coverage`, `pnpm check:type-check-debt` (re-measure: 4 ledger entries, 53 raw errors, none above its recorded number, surplus none), `node scripts/check-issue-citations.mjs`, `pnpm check:issue-citations`, `pnpm check:doc-authoring`, `pnpm check:ratchet-remedy-authority`, `pnpm check:nul-bytes`, `pnpm check:published-files`. Two gates first answered exit 3 (`check:dual-build-cjs-loads`, `check:i18n`: prerequisite not met, workspace not fully built, nothing measured); they were re-run after the build and exit 0. The first `check:type-check-debt` run was cut by my own 300s timeout (124); it re-ran under the lock after building `@objectstack/driver-mongodb`'s closure and exits 0. The whole lint workflow farm is CI's. ## Changeset None, and `skip-changeset` applies: the producer is a root `scripts/` file and the ledgers ship in no tarball. Measured: the 19 packages' `files[]` list `dist`, `README.md`, `CHANGELOG.md` (and spec's schema and docs paths), and a grep of those shipped paths for the ledger text and for `13470` finds 0 files, while the control `check-test-typecheck` finds 3 (cli, lint, runtime CHANGELOGs). ## Acceptance notes Not changed here, because they sit outside this card's `#13470` scope. Each is the same family (a tracker number answering 404), found in the files this PR touches: - `scripts/check-test-typecheck.mts`: `#13466` (lines 289, 625), `#8538` (939), `#6083` (1134). - Authored `_note` fields: `packages/rest` `#13377`, `#13378`, `#13454`; `packages/core` `#14613`; `packages/client` `#6083`. - `packages/client/test-typecheck-debt.json` was not one of the 19 and was not regenerated: its `_comment` predates the per-signature mechanism and is stale against the producer. A regeneration would move that line for a different reason than this card. ## Deviations from the dispatch order 1. The producer had 24 lines to re-anchor, not one (the card's own re-check requires all 24 to go). 2. `packages/rest` changes two lines, not one: its authored `_note` carried the same dead number. Landing site is as expected (`scripts/check-test-typecheck.mts` and the generated ledgers). Clause-② stays `no`: nothing here widens an accept set or a public surface. --- _Generated by [Claude Code](https://claude.ai/code/session_017VaLJnYwhPsanVCe9dMCJU)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2f2fa11 commit b253fad

20 files changed

Lines changed: 45 additions & 44 deletions

‎packages/cli/test-typecheck-debt.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"_comment": "Per-file tsc error debt of the @objectstack/cli TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/cli gen:test-typecheck-debt",
2+
"_comment": "Per-file tsc error debt of the @objectstack/cli TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total, because a total can hold while the errors underneath it are replaced wholesale: a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/cli gen:test-typecheck-debt",
33
"_note": "SEEDED, NOT REPAIRED, and that was this card's own triage ruling rather than this author's convenience: 28 errors across 3 of this package's 115 test files, measured at 5a5336b399 with the workspace closure built first, on the PR that first put those files in front of tsc. Repairing them in the same change would have buried the gate under a cleanup, which is how an onboarding stops landing; the ratchet only has to shrink from here. THIS PACKAGE REACHED THE HIDDEN STATE BY THE OTHER SPELLING, which is the part worth carrying to the next package: `tsconfig.json` here has no `exclude` at all. It declares `include: [\"src\"]`, and these 115 files live in a sibling `test/` tree the glob simply never reaches — the identical end state AGENTS.md forbids by naming the `exclude` spelling, arriving through a door that rule's text does not cover. Measured rather than read off the config: `tsc --noEmit --listFiles -p tsconfig.json` puts 1009 files in the program and 0 of the 115 among them, while 119 of 119 non-test `src/**` files and all 121 `src/**` test files ARE there — so the zero is the `include` line, not a probe that sees nothing. The directional control is `packages/drivers/driver-memory`, whose tsconfig carries no test exclusion: the same probe puts 40 of its 40 test files in the program. Under `tsconfig.test.json` the count is 115 of 115, plus the 3 package-root harness modules (`vitest.config.ts`, `vitest-tiers.ts`, `vitest-tiers.fixtures.ts`) and `test/helpers/serve-process.ts`, none of which any tsc program read before either. WHERE THE 28 CAME FROM, both directions attributed with no unexplained remainder: the same file population under the build config's inherited NodeNext semantics reports 144, and 144 is exactly what `scripts/check-type-check-coverage.mjs` had recorded for this package in its per-PACKAGE `TEST_DEBT` ledger — class for class on re-measurement (TS7006 x59, TS2835 x56, TS2339 x24, TS2307 x3, TS18046 x2). So this file does not add debt, it holds the SAME population one level finer, per file and per signature, and that `TEST_DEBT` entry graduated in the same change. 120 of the 144 dissolve under this program's vitest-matching module semantics (TS2835 x56 extension-less relative imports, the TS7006 x59 cascading above them, TS2307 x3, TS18046 x2) and were about the CHECK rather than the code; collapsing that cascade EXPOSED 4 more (TS18048 x4 in test/i18n-extract-action-description.test.ts, previously hidden behind an `any` from its two unresolved imports of `../src/utils/i18n-extract` and `../src/utils/i18n-coverage`). The 24 TS2339 survive the move unchanged, file for file and count for count. 144 - 120 + 4 = 28. A SECOND CONFIG-TIER PILE THAT IS NOT IN THIS LEDGER, recorded so nobody re-derives it: this package's test tree sits OUTSIDE the build config's `rootDir` (`src`), so with `rootDir` inherited the same program adds 116 x TS6059 — one per file in `test/`, saying nothing about any test. `tsconfig.test.json` widens `rootDir` to `../..` the way `packages/client`'s test config already does, and for one measured reason beyond the 116: three of these tests import fixtures from `examples/app-showcase/src/**`, which is outside this package entirely, so even `rootDir: \".\"` still reports 3 x TS6059. WHAT IS ALREADY GATED, and it is nearly all of the package: 112 of the 115 test files carry no entry here at all, so any error any one of them gains is red on arrival. ⚠️ This layer holds ZERO `@ts-expect-error` directives — measured across all 115 files plus the 3 root harness modules, not assumed — so unlike packages/spec and packages/client no pin was silently dead here, and none reports TS2578 under this program. The card's sharpest line ('a `@ts-expect-error` in any of those files is a phantom check') is therefore a statement about what WOULD happen, not about an existing dead pin. What the gap really cost is the other half: 144 real diagnostics that no gate has ever reported, and no way to write a type-level pin in this tree at all. THE PILE IS CONCENTRATED, which is the useful thing for whoever pays it down: test/data-model-rules.test.ts x23 is 23 of the 28 on its own, and all 23 are TS2339 property reads off a lint-diagnostic type ('message' x17, 'fix' x4, 'severity' x2) — one narrowing helper on that type is very nearly the whole ledger. The remaining 5 are 4 TS18048 in one file and a single TS2339 in another. RECORDED EXACTLY, no bootstrap margin: this layer has never been gated, so the first new error in it should go red rather than be absorbed. ⚠️ That includes test/run-dev-unbuilt-workspace.e2e.test.ts, a known repo-wide RUNTIME flake whose fix was in the merge queue when this landed: it type-checks clean and carries no entry here, so a type error it gains is red like any other. A flake in `vitest` is not a diagnostic in `tsc` and this ledger never sees one.",
44
"entries": {
55
"test/data-model-rules.test.ts": {

‎packages/connectors/connector-mcp/test-typecheck-debt.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"_comment": "Per-file tsc error debt of the @objectstack/connector-mcp TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/connector-mcp gen:test-typecheck-debt",
2+
"_comment": "Per-file tsc error debt of the @objectstack/connector-mcp TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total, because a total can hold while the errors underneath it are replaced wholesale: a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/connector-mcp gen:test-typecheck-debt",
33
"entries": {
44
"src/mcp-provider.test.ts": {
55
"TS2339: Property 'then' does not exist on type '…'.": 5

‎packages/connectors/connector-openapi/test-typecheck-debt.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"_comment": "Per-file tsc error debt of the @objectstack/connector-openapi TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/connector-openapi gen:test-typecheck-debt",
2+
"_comment": "Per-file tsc error debt of the @objectstack/connector-openapi TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total, because a total can hold while the errors underneath it are replaced wholesale: a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/connector-openapi gen:test-typecheck-debt",
33
"entries": {
44
"src/openapi-provider.test.ts": {
55
"TS2339: Property 'then' does not exist on type '…'.": 5

0 commit comments

Comments
 (0)