Add typecheck budget guard to catch type-instantiation regressions#555
Merged
Conversation
…teup Adds scripts/typecheck-budget.ts, which type-checks each composite package in isolation and gates its (deterministic, machine-independent) instantiation count against committed per-package budgets in scripts/typecheck-budget.json. Wired into CI as the `typecheck-budget` job and exposed as `bun run typecheck:budget`. Also documents the typecheck slowdown investigation (timeline, bisected culprit commits, root-cause analysis, and prototyped fixes) in docs/technical/typecheck-performance-investigation.md. https://claude.ai/code/session_018SckHLTLmkxKCSWyb74Lke
Closed
3 tasks
Coverage Report
File CoverageNo changed files found. |
…AI Text slice) Proof-slice for the typecheck-cost work: the dominant `packages/ai` check cost is the `FromSchema<typeof Schema>` conditional-type machinery (json-schema-to-ts), not the Workflow/CreateWorkflow generics. Converting the plain `type X = FromSchema<typeof Schema>` aliases to concrete types removes that per-use instantiation cost. This slice converts the AI Text task family + the foundational model types (ModelConfig/ModelRecord). Each concrete type is the type checker's exact resolution of the original FromSchema type (verified by a clean full `tsc -b`), so it is equivalent to the prior derived type; the schema constants remain the runtime contract. Budget baseline ratcheted to match. Measured (pinned tsc, deps prebuilt, isolated `tsc -p`): - ai: 564,545 -> 520,877 instantiations (this 7-file slice) - full-ai conversion projects to ~320k instantiations / -39% check time, with a ~-14% ripple on packages/test (tracked in #556) Tradeoff: a hot-path `Equal<X, FromSchema<...>>` drift guard is intentionally omitted because it would recompute FromSchema and defeat the win; the schemas stay the runtime source of truth. Refs #556. https://claude.ai/code/session_018SckHLTLmkxKCSWyb74Lke
… types Completes the FromSchema->concrete migration started in the AI Text slice. Converts the remaining plain and composite (Omit<...> / WithImageValuePorts<...>) type aliases across packages/ai to concrete types, removing the json-schema-to-ts conditional-type instantiation cost from the AI task input/output types. Each concrete type is the type checker's exact resolution of the original FromSchema type (verified by a clean full `tsc -b`); the schema constants remain the runtime contract. ModelConfig/ModelRecord and ChatMessage are referenced by name rather than inlined for readability. Four vector/embedding outputs that involve branded typed-array types (TextEmbedding, ImageEmbedding, VectorSimilarity) are intentionally left on FromSchema since they do not print to a clean concrete form. Measured (pinned tsc, deps prebuilt, isolated `tsc -p`): - ai: 564,545 -> 92,750 instantiations (-84%), 4.29s -> ~2.0s check (-52%) - test (ripple): 1,427,138 -> 947,215 instantiations (-34%), 12.4s -> ~9.2s Budget baselines ratcheted to match. Closes #556. https://claude.ai/code/session_018SckHLTLmkxKCSWyb74Lke
Closed
3 tasks
4 tasks
sroussey
pushed a commit
that referenced
this pull request
Jun 10, 2026
…-guard test The H-1 substitutions in PR #558 caused two CI failures: 1. `build` — MessageConversion.ts:52,174 stopped compiling because the new `readonly` modifier on `prompt` broke `Array.isArray()` narrowing (TS doesn't narrow readonly arrays via Array.isArray). 2. `typecheck-budget` — packages/ai went 92,750 → 152,539 instantiations (+64%), defeating PR #555's perf goal. ContentBlock plus FromSchema references in types.test-d.ts together blew the budget. PR #555 verified the inline literals are byte-equal to FromSchema's resolution, so the substitution was gratuitous tightening, not a safety win. The schema-vs-type drift risk is still real but addressed by the H-3 nightly drift guard. Changes: - Restore original inline `prompt` literal in AiChatTask.ts (ContentBlock import stays — used elsewhere). - Restore original inline `prompt` literal in ToolCallingTask.ts; drop unused ContentBlock import. - Simplify types.test-d.ts to assert expectTypeOf<X["prompt"]>().toEqualTypeOf<FromSchema<typeof S>["prompt"]>() for AiChat + ToolCalling (now true). Keep .not.toEqualTypeOf for ChunkRetrieval (intentional if/then/else divergence). - Exclude src/**/*.test-d.ts from packages/ai/tsconfig.json so typecheck:budget doesn't measure FromSchema cost in the test file. Nightly workflow's --typecheck engine is unaffected. MessageConversion.ts is unchanged — narrowing works again with the restored mutable arrays.
sroussey
added a commit
that referenced
this pull request
Jun 12, 2026
## @workglow/browser-control ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/task-graph ### Features - add bugs URL to package.json files across all packages and providers ### Bug Fixes #### task-graph,storage - cache restart-resume + SharedInMemory sync barrier (#552) ### Documentation #### task-graph - fix TaskOutputTabularRepository README examples for new constructor signature ## @workglow/javascript ### Features - add bugs URL to package.json files across all packages and providers ### Bug Fixes - tsgo issue ## @workglow/ai ### Features - add typecheck budget guard to catch type-instantiation regressions (#555) - add bugs URL to package.json files across all packages and providers ### Bug Fixes #### ai - export ChunkRetrievalInputSchema + nightly schema-vs-type drift guard (#565) ## @workglow/knowledge-base ### Features - add bugs URL to package.json files across all packages and providers ## workglow ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/storage ### Features - add bugs URL to package.json files across all packages and providers ### Bug Fixes #### task-graph,storage - cache restart-resume + SharedInMemory sync barrier (#552) ## @workglow/mcp ### Features - add bugs URL to package.json files across all packages and providers ### Bug Fixes #### mcp - thread run-scoped registry through discoverSchemas (#577) - resolve auth credentials through the run-scoped registry ## @workglow/util ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/test ### Features - add bugs URL to package.json files across all packages and providers #### supabase - add Supabase vector storage with pgvector support (#578) ### Bug Fixes #### mcp - thread run-scoped registry through discoverSchemas (#577) - resolve auth credentials through the run-scoped registry #### task-graph,storage - cache restart-resume + SharedInMemory sync barrier (#552) ### Tests - pin HF router provider for tool-calling conformance tests (#564) ### Chores - update deps ### Updated Dependencies - `@aws-sdk/client-sqs`: ^3.1068.0 - `@cloudflare/workers-types`: ^4.20260612.1 - `@types/dom-chromium-ai`: ^0.0.17 - `miniflare`: ^4.20260611.0 ## @workglow/tasks ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/job-queue ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/indexeddb ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/openai ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/llamacpp-server ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/mlx ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/electron ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/ollama ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/node-llama-cpp ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/aws ### Features - add bugs URL to package.json files across all packages and providers ### Chores - update deps ### Updated Dependencies - `@aws-sdk/client-sqs`: ^3.1068.0 ## @workglow/anthropic ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/google-gemini ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/postgres ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/stable-diffusion-server ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/supabase ### Features - add bugs URL to package.json files across all packages and providers #### supabase - add Supabase vector storage with pgvector support (#578) ## @workglow/playwright ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/sqlite ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/cloudflare ### Features - add bugs URL to package.json files across all packages and providers ### Chores - update deps ### Updated Dependencies - `@cloudflare/workers-types`: ^4.20260612.1 ## @workglow/huggingface-transformers ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/tf-mediapipe ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/chrome-ai ### Features - add bugs URL to package.json files across all packages and providers ### Chores - update deps ### Updated Dependencies - `@types/dom-chromium-ai`: ^0.0.17 ## @workglow/huggingface-inference ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/cactus ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/bun-webview ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/cli ### Features - add bugs URL to package.json files across all packages and providers ## @workglow/web ### Features - add bugs URL to package.json files across all packages and providers ### Chores - update deps ### Updated Dependencies - `@tailwindcss/vite`: ^4.3.1 - `tailwindcss`: ^4.3.1
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.
Summary
Adds a CI guardrail (
scripts/typecheck-budget.ts) that gates per-package TypeScript instantiation counts to catch type-level performance regressions at PR time. Instantiation counts are deterministic and machine-independent, making them reliable for detecting the kind of schema composition or generic explosion that can silently degradetscperformance.Changes
scripts/typecheck-budget.ts— New script that:packages/*/tsconfig.json,providers/*/tsconfig.json)tsc -bto emit.d.tsfilestsc --extendedDiagnosticsand extracts theInstantiationscount--updateto re-baseline,--jsonto emit raw measurements,--no-buildto skip warm build, and--toleranceto overridescripts/typecheck-budget.json— Initial budget baseline with instantiation counts for all 34 packages (tolerance 15%, floor 50k instantiations)docs/technical/typecheck-performance-investigation.md— Detailed investigation documenting:git bisect:16a94b54(MCPallOfspreading):packages/tasks289k → 6.77M instantiations (23×, already fixed)888da0e1(task-runner refactor):packages/ai0.9s → 3.4s check time (2×, durable).github/workflows/test.yml— Newtypecheck-budgetCI job that runs beforebuild, fails the PR on regressionspackage.json— Addedtypecheck:budgetscriptImplementation notes
Bun.Globto discover packages (fast, no external deps)InstantiationsandCheck timefromtsc --extendedDiagnosticsoutput via regextsconfig.tsbuildinfobefore each isolated check to force full re-check (deps already built)This guardrail is stable across CI runners (instantiations are deterministic) and catches exactly the class of regression that caused the 3.6× slowdown documented in the investigation.
https://claude.ai/code/session_018SckHLTLmkxKCSWyb74Lke