Skip to content

Add opt-in Tier-0 no-eval compiled validation fast path - #36

Merged
ushironoko merged 3 commits into
mainfrom
perf/tier0-closure-validator
Jun 17, 2026
Merged

Add opt-in Tier-0 no-eval compiled validation fast path#36
ushironoko merged 3 commits into
mainfrom
perf/tier0-closure-validator

Conversation

@ushironoko

Copy link
Copy Markdown
Owner

Summary

Adds an opt-in Tier-0 no-eval compiled validation fast path (safeParseCompiled / getCompiledValidate). It compiles a schema into a closure tree at construction time — no eval, no new Function, no codegen — so it runs where JIT tiers cannot: strict-CSP pages and edge runtimes (Cloudflare Workers, Deno Deploy, Vercel Edge). It removes the interpreter's megamorphic per-node dispatch and per-value dataset allocation.

The interpreter stays the source of truth; this is an opt-in parallel path. Piped, async, and non-specialized nodes fall back to ~run, byte-identical to safeParse on success and error paths.

Performance vs interpreter (full-materializing per-fixture sink, median of 5)

fixture JSC (Bun) V8 (Node)
object/flat 1.40x 2.21x
object/nested 1.14x 1.36x
array/number-100 1.26x 1.70x
array/object-50 1.33x 1.45x
error paths 1.10–1.23x 1.27–1.48x

Bare top-level primitives are a documented non-target (use safeParse directly). A 30-schema interleaved shared-IC guard shows zero V8 deopts and no regression on either engine.

Edge / CSP

Proven by execution (not by grep) under node --disallow-code-generation-from-strings — the same constraint Cloudflare Workers enforce. The compiled validator builds and runs with zero eval/Function. See test/workerd/smoke.ts.

Conformance

packages/tskm/test/compile.test.ts asserts byte-identical results (toStrictEqual) on success AND error paths, including piped-child-in-container cases that guard against an accept-invalid bypass, plus a fast-path-only-for-bare-leaf invariant. It doubles as a Stryker oracle (verified it kills the bypass mutant).

Notes

  • The eval tier (the higher ceiling) is intentionally out of scope (Tier-0 only).
  • Stryker wiring is documented but deferred until the mutation harness lands on main.

🤖 Generated with Claude Code

safeParseCompiled compiles a schema into a closure tree at construction time
(no eval / no new Function / no codegen), so it runs where JIT tiers cannot:
strict-CSP pages and edge runtimes (Cloudflare Workers, Deno Deploy, Vercel
Edge). It removes the interpreter's megamorphic per-node dispatch and per-value
dataset allocation, winning ~1.1-2.4x on container schemas across both V8 and
JSC, while staying byte-identical to safeParse on success and error paths.

The interpreter remains the SSoT; this is an opt-in parallel path. Piped, async,
and non-specialized nodes fall back to ~run (defense-in-depth against an
accept-invalid bypass), an invariant locked by a test. A bare top-level
primitive should use safeParse directly (documented entry overhead).

- packages/tskm/src/compile.ts: closure compiler, getCompiledValidate (WeakMap
  keyed off the schema value), safeParseCompiled
- packages/tskm/src/index.ts: opt-in exports
- packages/tskm/test/compile.test.ts: byte-identical conformance + piped/refined
  child bypass guards + fast-path-only-for-bare-leaf invariant (Stryker oracle)
- bench/validator: full-materializing per-fixture sink, no-regression gate,
  30-schema interleaved shared-IC guard (zero V8 deopts)
- test/workerd/smoke.ts: no-eval property proven by execution under
  node --disallow-code-generation-from-strings

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pkg-pr-new

pkg-pr-new Bot commented Jun 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

bun add https://pkg.pr.new/@tskm/compiler@26bd3c1
bun add https://pkg.pr.new/@tskm/core@26bd3c1
bun add https://pkg.pr.new/@tskm/vite@26bd3c1

commit: 26bd3c1

ushironoko and others added 2 commits June 17, 2026 14:01
The compiled validator specialized schemas by their public `type` string, so a
foreign schema with a colliding `type` (e.g. "string"), no pipe and a stricter
`~run` was specialized and had its `~run` bypassed, accepting input the
interpreter rejects. Dispatch on factory identity (`schema.reference`) instead in
both `compile()` and `primitiveCode()`; non-native schemas fall back to their own
`~run`. Document the `reference` trust boundary and pin the routing with a
type-string collision battery plus a contract test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
compile.ts was auto-included in the mutation `mutate` set, but the existing tests
only covered the security-critical routing, leaving its specialized walkers at
~39% and dragging the package under the 80% break threshold (70.85%). Add a
comprehensive interpreter-parity battery (`toStrictEqual` vs the interpreter as a
differential oracle) covering every specialized path: the 3/5-key strip unrolls,
the wide/general primitive object, the array item-inline codes, faithful-optional
drop and defaults, rest modes, declared `__proto__`, the abort knobs, per-slot
type-order permutations, and custom-message branches. Package score 70.85 -> 83.58.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ushironoko
ushironoko merged commit e63aeb5 into main Jun 17, 2026
7 checks passed
@ushironoko
ushironoko deleted the perf/tier0-closure-validator branch June 17, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant