chore(ci): ratchet TypeScript errors, because npm test does not typecheck (#1980)

Vitest transpiles and discards types, so a type error passes all 18 000 tests
and only surfaces in npm run build several minutes later. That happened twice
on 2026-08-27: a widened union in the MCP server that a second declaration in
lib/events/types.ts still contradicted, and an interface that would not assign
into Record<string, unknown>[] because interfaces have no implicit index
signature. Both were caught by the build. Neither was caught by the tests,
which is the wrong order to learn it in.

This is not just a faster copy of the build job. tsc --noEmit also covers
__tests__ files, which the Next.js build never compiles, and that is where all
539 baseline errors live.

Baselined per FILE rather than per error code, unlike the lint ratchet: the
legacy errors sit in a handful of old test files and TS2322 is common enough
that a code-keyed budget would let a real regression hide behind a legacy fix
somewhere else.

Measured: 36s cold, which is what CI pays, and 4.4s warm locally.

Verified the gate fires by introducing a deliberate type error and watching it
fail with the exact location, then restoring.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-27 17:53:04 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Opus 5
parent e41cf50afe
commit 304baf1089
6 changed files with 243 additions and 0 deletions
+13
View File
@@ -58,6 +58,19 @@ jobs:
# baseline ratchets down as legacy errors get fixed.
run: npm run check:lint
- name: Typecheck ratchet (no new TypeScript errors)
# `npm test` does not typecheck: vitest transpiles and discards types,
# so a type error passes all 18 000 tests and only surfaces in the
# build. That happened twice on 2026-08-27. This also covers __tests__
# files, which the Next.js build never compiles, so it is not merely a
# faster copy of the build job.
#
# Baselined per FILE in scripts/checks/typecheck-baseline.json (539
# legacy errors across 83 files, all in test files) and ratchets down.
# Per-file rather than per-error-code on purpose: a code-keyed budget
# would let a real regression hide behind a legacy fix elsewhere.
run: npm run check:types
- name: Antipattern ratchet (no new MFA-bypassing routes / naive öre-rounding)
# Fails only if a PR ADDS a route that hand-rolls supabase.auth.getUser()
# instead of the MFA-enforcing guard, or a new Math.round(x*100)/100.