Uh oh!
There was an error while loading. Please reload this page.
Pay down 17 of packages/rest's test-typecheck ledger, and refute the cause it records - #12625
Merged
Merged
Conversation
Two annotation-only classes, both repaired in the form this package's already-green test files use: - TS18048 x13, all in `export-integration.test.ts`: `getRoutes().find()` is `Route | undefined`, so every `route.handler(...)` below read as possibly-undefined. Asserted non-null at the two lookup sites rather than at the thirteen call sites. `!` erases, so no call receives a different value than it did before. - TS7006 x4: `ReturnType<typeof vi.spyOn>` leaves `mock.calls` untyped, so each `.map`/`.filter` callback parameter was implicitly `any`. Annotated `unknown[]`, the form `rest-5xx-status-passthrough.test.ts` already uses. Ledger regenerated, not hand-edited: four entries reach zero and are deleted, `export-integration.test.ts` re-records 17 -> 4. 37 -> 20 errors across 13 -> 9 files. No number is raised. The remaining 20 are NOT repaired, on purpose: they need a fixture's data or a producer's signature changed, not an annotation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 13 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-litant
marked this pull request as ready for review
August 27, 2026 01:30
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Part of #12573
Part of, not a closing keyword. The card asks for the ledger to be paid down; this pays 17 of the 33 in scope and reports the other 16 as questions rather than repairing them, so merging should not close the card. The dispatch order said to use a closing keyword — flagged here rather than silently chosen, per "report what you measure; do not reconcile". Switch it before marking ready if the card should close anyway.Ruling 1 first: the ledger's own stated cause is refuted
The ledger's
_commentclaims the errors are "almost all of them fixture literals annotated with a schema OUTPUT type (z.infer) while holding an authored INPUT literal."0 of 33. Not "few" — zero.
The zero is a reading, not a broken grep. And there is a reason: that clause is #5478/#5543's finding —
registerObject'sschemaparameter annotated with thez.inferOUTPUT type — and #5543 was closed as completed on 2026-08-08 by PR #6786. This ledger was created 18 days later and stamped with the already-fixed cause. Filed as #12624, together with the reason it cannot be corrected in place:LEDGER_COMMENTis a constant inscripts/check-test-typecheck.mtsand--updaterewrites_commentfrom it on every regeneration. I corrected the prose, re-ran the regenerator, and watched the refuted claim come back — so this PR leaves_commentbyte-identical and the ledger diff is entries-only.What the 33 actually are — four stories, exact counts
TS2554registry.registerObject(x)missing the requiredpackageIdTS18048getRoutes().find()isRoute | undefinedTS7006mock.callscallback parametersTS2345IHttpRequest'sheaders/pathTwo corrections to the card's own numbers, reported rather than reconciled:
TS2554span six files, not five (export-integration×4,import-integration×3,rest-meta-save-receipt-envelope×3,import-job-integration×2,import-dryrun-parity×1,rest-write-response-formula×1);tsconfig.test.json's header records 489 files in the program measured at5fbd58e0d; this run measures 640. The 149 test files it records are unchanged.Fence re-derived from PR #12421's own diff (still open, 5 files): of the 13 ledgered files it holds only
src/rest.test.ts. Untouched here, its entry of 4 unchanged.The 17 repaired — both annotation-only, both in the form this package already uses
TS18048×13, all inexport-integration.test.ts.Array.prototype.findreturnsRoute | undefined, so all thirteenroute.handler(...)calls read as possibly-undefined. Asserted non-null at the two lookup sites rather than at the thirteen call sites — the lookup either finds the routeregisterRoutes()just registered or the boot is broken. Six already-green siblings in this package use exactly this form (e.g.analytics-dataset-where-gate.test.ts:100).!erases at compile time, so no call below receives a different value than before.TS7006×4. Thevi.spyOnreturn type leavesmock.callsuntyped, so each.map/.filtercallback parameter was implicitlyany. Annotatedunknown[]— the form the greenrest-5xx-status-passthrough.test.ts:425already uses.Neither emits different JavaScript. Ledger regenerated, not hand-edited: four entries reach zero and are deleted,
export-integration.test.tsre-records 17 → 4. The regenerated diff moved only where I worked — every other entry, including the fencedrest.test.ts: 4, is byte-identical. 37 → 20 errors across 13 → 9 files. No number is raised.The 16 NOT repaired — ruling 6, and they are not typing questions
TS2554×14.registry.registerObject(schema, packageId, …)requirespackageId; the siblingregisterItemon the same class declares the same parameter optional, and both feed the identicalapplyProtection(item, { packageId }). That helper documents the package-less case as intended: "leave the item alone so that DB-only / test fixtures don't acquire an unexpected_provenancefield." So supplying apackageIdto satisfy the compiler stamps_packageIdand_provenance: 'package'onto the fixture — it changes what the test registers. Routing through the engine facade instead is not neutral either: it defaults to'__runtime__'and mutates the schema by auto-assigningfield.namefrom each key.That is a fixture's data, not its annotation ⇒ ruling 6 says stop and report. Filed as #12623, with the blast radius: 82 single-argument call sites repo-wide, of which 68 sit in
objectql(55),runtime(9) andplugins(4) — none of which has a test-layer tsc program, so the same latent error is unmeasured everywhere except here.TS2345×2 (meta-public-book-grant.test.ts:138,rest-batch-size-cap.test.ts:152).IHttpRequestrequiresheadersandpath; these request literals omit both. Adding them changes what the handler receives, andas any— the form the surrounding file uses — is forbidden by the card. Same disposition: data, not annotation.Anti-vacuity — the gate still says no
tsc -p tsconfig.test.json --noEmit --listFiles: 149src/**/*.test.tsstill in the program (640 files total), and all five edited files are in it — so these repairs were measured, not merely unopposed.Planted a real type error (
const __plant_12573: number = 'not a number';) inrest-unclassified-fault-status.test.ts— a file this PR repaired, whose ledger entry it deletes, so it is now unlisted and any error must red. Mutation confirmed on disk before any verdict was read (marker count 1, bloba46e4c50…→078d4759…). The gate exited 1 and named the file:Restored under a
trap … EXIT INT TERMwith absolute paths, viagit checkout HEAD --plus the absolute path (never bare). Restore proved by blob hash, not by an exit code: worktreea46e4c50e6a23925b83015701c1ede06a8e40e84==HEAD:blob, marker count 0,git diff HEADempty,git status --porcelainempty. The repairs were committed before this leg soHEADwas a real restore point.Verification
All on
0886595c2, the final commit.pnpm --filter @objectstack/rest test— 149 files / 2441 tests passed,VERDICT command-exit 0pnpm --filter @objectstack/rest typecheck(tsc --noEmit+check:test-typecheck) — exit 0node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(it derives its own changeset; 6 changed paths). All matched + convention-triggered families run, exit codes captured before any pipe:check:cross-package-test-inputs,check:dispatcher-error-vocabulary,check:objectql-double-limit,check:page-declaration-shape,check:published-files,check:slot-lookup,check:test-source-alias,check:type-source-resolution,check:query-options-erasure,check:engine-double-contract,check:where-matcher,check:nul-bytes,check:type-check-coverage,check-ci-filter-parity,check-comment-mask-adoption,check-cross-package-test-inputs,check-plugin-teardown-shape,check-affected-docs— all exit 0.check:type-check-debt --re-measurefirst refused to run (a prerequisite refusal, not a red gate: 32 workspace dependencies had no built type entry point, because I had built only@objectstack/rest's own closure). Re-run after building the full closure exactly aslint.ymldoes — result recorded in the report on the card.packages/specfamilies under "THE LAYOUT MOVED" arehintCoversreads an extensionless module specifier as a filesystem path, so 9packages/specgate families can never be MATCHED to a change set — silent under-derivation on every dispatch #12514 — not refiled.Changeset: none,
skip-changesetlabel applied. Measured against the repo's rule rather than recalled:packages/rest'spackage.jsonpublishesfiles: ["dist","README.md","CHANGELOG.md"], and this PR changes onlysrc/**/*.test.ts(excluded from the build config) plustest-typecheck-debt.json— nothing published moves.scripts/check-empty-changeset.mjsdocuments that an empty-frontmatter changeset is a real input tochangesets/actionand buys nothing the label does not, so the label is the mechanism here and an empty changeset would be the wrong answer.Scope
No production source touched.
packages/rest/src/rest-server.ts,packages/rest/src/rest.test.ts,packages/client/**andcontent/docs/releases/**are all untouched. The two out-of-scope findings are filed as separate unlabelled issues (#12623, #12624) and not folded into this PR.Generated by Claude Code