Skip to content

Latest commit

 

History

History
569 lines (463 loc) · 116 KB

File metadata and controls

569 lines (463 loc) · 116 KB
type Workspace Package
title @pmndrs/text-benchmarks
description Provides the shared interactive and automated benchmark product surface.
resource ../../apps/benchmarks
workspace_package @pmndrs/text-benchmarks
documentation_type reference
source_digest sha256:28a3fe3c5278e7412cdf26894a208dca2dfecd856724bdf2fbdc1c46a7b50f70
tags
package
benchmarks
react
vite
product-e2e
sources
id resource title
manifest
../../apps/benchmarks/package.json
Package manifest
id resource title
vite-config
../../apps/benchmarks/vite.config.ts
Benchmark development and preview server configuration
id resource title
benchmark-plan
../planning/benchmark-plan.md
Benchmark plan
id resource title
benchmark-ipsum
../../apps/benchmarks/src/workloads/benchmark-ipsum/scene.ts
Canonical benchmark ipsum corpus
id resource title
advanced-shaping-workload
../../apps/benchmarks/src/workloads/advanced-shaping/scene.ts
Authored Advanced Shaping workload timeline
id resource title
live-text-scene
../../apps/benchmarks/src/workloads/shared/live-text-scene.ts
Public-API-facing live Text scene contract
id resource title
live-text-scene-registry
../../apps/benchmarks/src/workloads/live-text-scenes.ts
Single-paragraph workload scene registry
id resource title
benchmark-font-assets
../../apps/benchmarks/src/workloads/font-assets/index.ts
Canonical selected-technique font-asset adapter
id resource title
benchmark-font-asset-contract
../../apps/benchmarks/src/workloads/font-assets/contracts.ts
Typed fixture delivery request and result contract
id resource title
benchmark-runtime-font-assets
../../apps/benchmarks/src/workloads/font-assets/runtime.ts
Target-v1 FontLoader ownership, source-font path, and delivery instrumentation
id resource title
runtime-fallback-parity-probe
../../apps/benchmarks/vitexec/runtime-fallback-parity.probe.ts
Baked and runtime delivery parity probe
id resource title
slug-role-scenes
../../apps/benchmarks/src/benchmark/targets/conformance/raster/slug-role-scenes.ts
Slug release-role scene definitions
id resource title
slug-role-scene-evidence
../../apps/benchmarks/fixtures/results/slug-role-scenes-chromium149.json
Retained Slug release-role evidence
id resource title
slug-outline-research
../planning/slug-outline-research.md
Slug outline architecture
id resource title
slug-external-render-parity-probe
../../apps/benchmarks/vitexec/slug-external-render-parity.probe.ts
Fully external Slug public-rendering parity probe
id resource title
slug-external-render-parity-evidence
../../apps/benchmarks/fixtures/results/slug-external-render-parity-chromium149.json
Retained fully external Slug rendering evidence
id resource title
icon-grid-evidence
../../apps/benchmarks/fixtures/results/icon-grid-retained-evidence-chromium149.json
Retained complete icon-grid traversal evidence
id resource title
raster-technique-compare
../../apps/benchmarks/src/surfaces/conformance/scenes/raster-technique-comparison.ts
Surface-owned realtime MSDF and Slug GPU comparison
id resource title
low-level-raster-reference
../../apps/benchmarks/src/benchmark/low-level/raster/source-outline-reference.ts
Shared low-level source-outline oracle
id resource title
external-raster-product-target
../../apps/benchmarks/src/benchmark/targets/product/external-raster-proof.ts
External raster public-API product proof
id resource title
react-text-product-target
../../apps/benchmarks/src/benchmark/targets/product/react-text.ts
React Text reconciliation product target
id resource title
v1-bitmap-proof
../../apps/benchmarks/src/v1-bitmap-proof.ts
Target-v1 retained Bitmap browser proof
id resource title
v1-mtsdf-proof
../../apps/benchmarks/src/v1-mtsdf-proof.ts
Target-v1 retained MTSDF browser proof
id resource title
v1-slug-proof
../../apps/benchmarks/src/v1-slug-proof.ts
Target-v1 retained Slug browser proof
id resource title
v1-compose-proof
../../apps/benchmarks/src/v1-compose-proof.ts
Target-v1 composed canonical-shader browser proof
id resource title
paragraph-contracts
../../apps/benchmarks/src/benchmark/targets/conformance/paragraph-contracts.ts
Public Rust paragraph conformance target
id resource title
bitmap-text-product-target
../../apps/benchmarks/src/benchmark/targets/product/bitmap-text.ts
Finite Bitmap public Text product target
id resource title
mtsdf-text-product-target
../../apps/benchmarks/src/benchmark/targets/product/mtsdf-text.ts
Finite MTSDF public Text product target
id resource title
slug-text-product-target
../../apps/benchmarks/src/benchmark/targets/product/slug-text.ts
Finite Slug public Text product target
id resource title
bitmap-finite-scene
../../apps/benchmarks/src/benchmark/low-level/raster/bitmap-finite-scene.ts
Shared finite Bitmap scene and exact CPU-reference capture
id resource title
bitmap-conformance-line
../../apps/benchmarks/src/techniques/bitmap/conformance-line.ts
Target-v1 committed Bitmap conformance paragraph
id resource title
bitmap-conformance-capture
../../apps/benchmarks/src/benchmark/targets/conformance/raster/bitmap-capture.ts
Target-owned finite Bitmap conformance capture
id resource title
rgba-readback
../../apps/benchmarks/src/benchmark/low-level/raster/rgba-readback.ts
Renderer-neutral RGBA8 readback normalization
id resource title
bitmap-atlas-metadata
../../apps/benchmarks/src/techniques/bitmap/metadata.ts
Bitmap technique atlas metadata inspection
id resource title
mtsdf-raster-configuration
../../apps/benchmarks/src/techniques/mtsdf/metadata.ts
MTSDF technique configuration inspection
id resource title
slug-raster-configuration
../../apps/benchmarks/src/techniques/slug/metadata.ts
Slug technique allocation inspection
id resource title
bitmap-persistent-scene
../../apps/benchmarks/src/techniques/bitmap/persistent-scene.ts
Bitmap live Text technique adapter
id resource title
mtsdf-persistent-scene
../../apps/benchmarks/src/techniques/mtsdf/persistent-scene.ts
MTSDF live Text technique adapter
id resource title
slug-persistent-scene
../../apps/benchmarks/src/techniques/slug/persistent-scene.ts
Slug live Text technique adapter
id resource title
renderer-lifecycle
../../apps/benchmarks/src/renderer/webgpu-renderer.ts
Shared renderer creation and disposal lifecycle
id resource title
runtime-world
../../apps/benchmarks/src/benchmark/runtime-world.ts
Koota benchmark runtime trait schema
id resource title
workload-catalog
../../apps/benchmarks/src/workloads/catalog.ts
Typed live-workload policy catalog
id resource title
icon-grid-workload
../../apps/benchmarks/src/workloads/icon-grid/scene.ts
Retained Icon Grid workload instance and public Text example
id resource title
application-routes
../../apps/benchmarks/src/app.tsx
Main and Presentation route entry
id resource title
harness-route
../../apps/benchmarks/src/routes/harness-route.tsx
Shared Main and Presentation provider identity
id resource title
harness-controller
../../apps/benchmarks/src/controllers/harness-controller.tsx
URL, transition, presentation, and execution state machine
id resource title
harness-scene
../../apps/benchmarks/src/surfaces/harness/scene.tsx
Benchmark and conformance scene composition
id resource title
persistent-harness-layout
../../apps/benchmarks/src/surfaces/harness/persistent-layout.tsx
Persistent renderer provider and exclusive action adapter
id resource title
harness-layout
../../apps/benchmarks/src/components/harness-layout.tsx
Main and Presentation application chrome
id resource title
bitmap-live-viewport
../../apps/benchmarks/src/surfaces/benchmark/bitmap-text-viewport.tsx
Bitmap persistent live-text viewport controller
id resource title
sdf-live-viewports
../../apps/benchmarks/src/surfaces/benchmark/sdf-text-viewports.tsx
MTSDF and Slug persistent live-text viewport controllers
id resource title
benchmark-surface
../../apps/benchmarks/src/surfaces/benchmark/benchmark-surface.tsx
Authored workload and technique surface dispatcher
id resource title
comparison-workload-viewport
../../apps/benchmarks/src/surfaces/benchmark/comparison-workload-viewport.tsx
Retained comparison workload React viewport
id resource title
raster-conformance-session
../../apps/benchmarks/src/benchmark/targets/conformance/raster/contracts.ts
Low-level raster conformance session contract
id resource title
mtsdf-conformance-capture
../../apps/benchmarks/src/benchmark/targets/conformance/raster/mtsdf-capture.ts
Target-owned finite MTSDF capture lifecycle
id resource title
slug-conformance-capture
../../apps/benchmarks/src/benchmark/targets/conformance/raster/slug-capture.ts
Target-owned finite Slug capture lifecycle and role proofs
id resource title
comparison-workload
../../apps/benchmarks/src/surfaces/benchmark/scenes/comparison-workload.ts
Retained multi-technique workload scene
id resource title
comparison-measurement-preview
../../apps/benchmarks/src/benchmark/probes/comparison-workload-preview.ts
Isolated-canvas adapter for Slug performance measurements
id resource title
tsl-conformance-target
../../apps/benchmarks/src/benchmark/targets/conformance/tsl-baseline.ts
Deterministic TSL renderer conformance target
id resource title
live-text-update-probe
../../apps/benchmarks/scripts/run-live-update-latency-probe.mts
Input-to-visible-frame latency and glyph-transition probe
id resource title
conformance-surface
../../apps/benchmarks/src/surfaces/conformance/conformance-surface.tsx
Host-borrowing conformance surface hierarchy
id resource title
presentation-framerate-sweep
../../apps/benchmarks/vitexec/presentation-framerate-sweep.probe.ts
Complete Presentation workload performance sweep
id resource title
workflow-runner
../../apps/benchmarks/scripts/workflows.mts
Specialized workflow runner
id resource title
workflow-output
../../apps/benchmarks/scripts/workflow-output.mts
Vitexec failure-output classifier
id resource title
raster-technique-compare-probe
../../apps/benchmarks/vitexec/raster-technique-compare.probe.ts
Realtime comparison product probe
generated
by at
openai-codex/gpt-5.6
2026-08-11T04:57:21Z

Package reference: @pmndrs/text-benchmarks

Status: ✅ Milestone 10 renderer-neutral extensibility and retained Presentation are complete

The application now also contains focused target-v1 browser proofs for Bitmap, MTSDF, Slug, and Worker preparation while the full Presentation remains on the explicit merged-v0 harness subpath. Each raster proof renders through the maintained Three adapter on native WebGPU and forced WebGL2, mutates the retained text, and asserts draw plus storage identity rather than treating first pixels as sufficient evidence. Each raster proof also reports the retained Text.gpuBytes and fails when a visibly populated draw claims no GPU residency, so the accessor is proven against live engine resources rather than a unit fixture. The Worker proof distinguishes call-time snapshots, later desired state, supersession, abort, progress, and one reusable module Worker.

The public paragraph-contract target now passes its complete exact matrix through the retained Rust path: two bidi layouts, nine line-policy layouts, twelve CJK layouts, and one UIKit-shaped measurement/layout seam. The UIKit fixture models the frame ABI's f32 style input rather than the deleted TypeScript engine's JavaScript-double input. Its final-line baseline and centered glyph row are derived independently from the f32 line box followed by f64 accumulation and one final f32 publication; the exact full-layout hash remains a deterministic byte contract rather than a tolerance assertion.

A fifth proof covers material customization over the canonical Bitmap command-buffer path. It renders one paragraph with the default Bitmap material, then renders the same Rust-produced draw with a defineTextMaterial factory that starts from createDefaultMaterial() and changes only its final colour. The verification compares the two passes on the same page rather than against a stored golden: an identical lit-pixel set proves the custom material inherited canonical placement, snapping, and coverage, and an empty green channel proves it still emitted its own output.

The finite Bitmap conformance lane now drives that adapter directly. bitmap-finite-scene builds its paragraph with the target-v1 Text and reads the CPU reference from the LoadedFont raster data it already holds, which removes the second raster load and decode the merged-v0 path performed. A committed Text replaces the awaited readiness promise: the paragraph is parented, updateMatrixWorld reconciles it, and a preparation failure surfaces as a thrown error rather than an empty frame. The migrated lane reproduces the CPU compositor in zero mismatched bytes and returns the merged-v0 full-frame hash a47930d3…e893 with the same 5,930 lit and 3,473 half-coverage pixels and [68, 18, 313, 112] ink bounds, so the oracle changed renderer without changing what counts as correct. Both bitmap-text-webgl2 and source-outline-bitmap-webgl2 consume this scene, so both moved together.

The three live technique scenes moved to target-v1 next. techniques/{bitmap,mtsdf,slug}/persistent-scene.ts now build a standalone Text — an implicit batch of one, deliberately left off TextGroup so the single-paragraph adapter path stays exercised and their drawCount stays directly comparable with merged v0 — from the LoadedFont that workloads/font-assets already produced, commit it by parenting and forcing updateMatrixWorld, and read error plus explicit measureLayout() or inspectLayout() results instead of awaiting readiness. Flat merged-v0 properties become nested contentBox, style, and paint, with the paragraph measure expressed as an exact width constraint and the live colour as #ffffff, which resolves through the same transfer function as the numeric constant it replaces. Because a rejected generation would otherwise leave the failed candidate font leased and undisposable, each scene commits through one apply-or-roll-back step that restores the previously committed inputs before rethrowing.

Their presentation transitions are now owned by the application. Merged v0 exported captureBitmapGlyphPositions and createBitmapGlyphPositionTransition, which packaged glyph identity matching and interpolation together for Bitmap only. Target-v1 exposes explicit Rust inspection and topology-guarded renderer presentation writes, so techniques/shared/glyph-origin-transition.ts owns the application policy once for all three techniques: it matches glyphs on font handle, glyph id, cluster, and occurrence index, interpolates toward the shaped origins rather than the current displayed ones, writes through setGlyphOrigins, clears the overrides when settled, and reports matchedGlyphs so the existing viewport telemetry keeps its meaning. Bitmap keeps its host-driven progress because its React viewport already animates the timeline; MTSDF and Slug, whose surfaces do not drive progress, advance the same smoothstep from their own frame clock and gain the transition they previously lacked.

Whether a reflow may interpolate at all is decided once, in glyphOriginPolicy, and keyed to the kind of change rather than the technique. That identity keys a glyph on its UTF-16 source cluster, which survives a reflow but says nothing about visual order: under bidi, inserting one character reorders a whole run, so a typewriter reveal that kept matching slid glyphs across their neighbours toward positions they never travelled through. A change to the source text — or to the fixture, script, or features that decide which glyphs the text shapes into — therefore snaps, clearing the overrides so the committed layout stays authoritative and reporting zero matches rather than a count it did not animate. Geometry and style changes leave the shaped run and its visual order intact, so font size, layout width, anchor, and device pixel ratio still interpolate. A snapping reflow also skips captureGlyphOrigins entirely, so it never allocates the per-glyph map it would not have read. All three viewports publish data-presentation-transitioned beside the matched and target counts, and the bitmap viewport's host-driven timeline runs only when the scene reports that it transitioned.

The live update itself is synchronous. update applies and shapes one generation in the caller's own turn, so an ordinary text, font-size, layout-width, anchor, or device-pixel-ratio change is visible on the next frame the host draws. The promise belongs on loading: a font fixture whose bytes must be fetched and decoded is staged through loadFontFixture, which lets a fixture swap load behind text that stays on screen, and RetainedFontFixtureController splits into that asynchronous load and a synchronous transactional commit. Nothing in front of update coalesces, debounces, or defers, because such a queue drops shaping work during continuous animation: the framerate stays pinned while the presented paragraph lags the state the surface is already rendering from, which is how an expensive reshape stays invisible until someone watches a workload. probe:live-update-latency measures that directly from the presented canvas, and its typewriter observation opens on the very task that pauses a full-speed reveal, so every further distinct frame is the harness still catching up rather than new content.

Every benchmark surface now loads through the target-v1 FontLoader and renders through the /three adapter; the merged-v0 harness subpaths and the dual-shape BenchmarkFontAsset bridge that carried unmigrated scenes are gone, so a scene reads its registered font from loaded.font and its decoded raster from loaded.data. A fresh matrix after the move rendered all seven workloads visibly for Bitmap, MTSDF, and Slug on WebGPU and forced WebGL2 with one renderer per case.

The technique-generic comparison workload layer has now moved off that harness path. ComparisonWorkloadEntry holds Text<AnyRasterTechnique>, and every workload factory receives the LoadedFont the shared target-v1 FontLoader already produced, so no comparison scene names or loads a raster module. Type erasure happens once, at the font: LoadedFont is covariant in its technique, so a concrete LoadedFont<typeof bitmap> widens to LoadedFont<AnyRasterTechnique> and every Text, TextGroup, and TextUpdate downstream is uniformly erased without a cast. Erasing at the Text instead does not compile: the set method and the font accessor make Text invariant in its technique. TextGroup no longer receives the selected technique at construction; its shared Rust session and renderer policy derive each draw's technique from the loaded font binding.

Batching is a per-workload policy on the definition rather than a host-wide rule. Text ladder, Zoom text, Icon grid, Off-axis / 3D, Dynamic layout, and Paint & effects mount under one shared TextGroup, so every paragraph in the workload enters one Rust frame transaction and shared render plan; compatible policy packets may share physical storage and one draw. Icon grid's recycled icon and label Texts share that session across two font fixtures because both load through the one registry-scoped runtime. Paragraph stress stays standalone: it is a single Text holding a large repeated-ipsum body, already a session of one, and keeping it standalone holds both adapter paths under test. The group takes a grow capacity so its retained staging and output regions settle for the workload rather than repeatedly growing.

Batching shares preparation and GPU resources, not draws. Target-v1 emits one mesh per packed glyph run and a run never spans paragraphs, so the shared group leaves the draw topology of each paragraph exactly as it was. Measured at the settled workload mount, every deterministic cell of the technique-by-backend matrix reports the same drawCount before and after the move — Text ladder 35 for Bitmap and 19 for MTSDF and Slug, Off-axis / 3D 12 and 1, Dynamic layout 20 and 3, Paint & effects 18 and 1, Paragraph stress 1,120 and 1, Zoom text 1 throughout. Icon grid is the one workload whose count is not comparable between runs because it auto-pans from mount, so its visible window differs by sample instant.

Publication replaced readiness. Target-v1 has no per-Text promise: parenting a workload under its batch root and calling updateMatrixWorld shapes, lays out, and packs it synchronously, after which layout is readable and error is meaningful. A rebuild therefore stages its root off-scene, publishes once, positions from the committed layouts, and only then swaps the live scene. The retained font-fixture swap collapsed from an asynchronous two-phase rollback to set({ font }) plus one publication, because the replacement LoadedFont is already resolved when the swap begins.

The visible-pixel counts printed by benchmark:presentation are not a regression gate. The matrix samples live animated scenes at whatever phase the soak happens to end on, and two runs of identical code disagree in roughly half of the 42 cells — Paragraph stress alone ranged from 25,339 to 40,708 across two untouched merged-v0 runs, because the harness animates that workload's own font size and measure. What the matrix proves is its per-case line: all seven workloads visible, one renderer per case, across every technique and backend. Deterministic regression evidence lives in the headless conformance suite and its stored frame hashes.

The primary product surface is organized for humans by mode, technique, backend, and workload. Benchmark mode is the default live control plane. Conformance mode combines live GPU inspection with finite visual correctness checks; finite CPU-reference work begins only through the explicit run action rather than during workload navigation. Internal target/scenario terms remain runner architecture and do not appear as the primary controls. Figma-backed tokens and components remain design inputs, while the product information architecture may diverge from the wireframe.

The MSDF / Slug comparison workload owns one renderer, two equal RGBA8 render targets, and one fullscreen TSL composition graph. Both candidates share authored text, layout dimensions, camera, physical target size, zoom, and pan. The heatmap samples both candidate textures directly with no readback or CPU composition: black agrees, red marks extra MSDF coverage, cyan marks extra Slug coverage, and intensity is amplified eight times. A deterministic delayed-peer probe proved that independently prepared retained Text objects could otherwise expose one new candidate beside one old candidate. The scene now keeps sampling the last complete target pair while both updates prepare, publishes both retained objects in one JavaScript task, and refreshes or resizes both targets together only after the pair succeeds. Failure rolls both objects back; abort disposes only after the queued update settles. This remains private comparison coordination rather than a renderer-wide grouped-publication API. Explicit conformance runs and their follow-up visual captures execute as serialized jobs borrowing the route renderer; the retained scene pauses during each job and resumes after success, failure, or abort without replacing its canvas or leaking finite renderer state into the next frame. The permanent hardware-browser probe proves custom text, 4× zoom, responsive tab switching, zero automatic finite capture, abort and successful-capture recovery, a peak renderer concurrency of one, exact WebGPU backend initialization, and a live canvas; forced WebGL2 proves the same lifecycle without shader or validation errors. Run both backend lanes with pnpm scripts run benchmark:raster-comparison.1

The external-raster target is the product gate for the private glyphExample extension package. It starts from the public source-font fallback so source bytes are legitimately available, runs the package runtime baker and generic artifact attachment, publishes a cold Text, then replaces its text through the warm matrix-update lifecycle. WebGPU and forced WebGL2 must retain the draw object and geometry, submit one draw, produce visible pixels, and return the same deterministic readback hash. The focused workflow is pnpm scripts run benchmark:external-raster; it fails on page, console, shader, backend, pixel, or lifecycle errors.

Conformance inspection distinguishes retained GPU capacity from submitted logical content. In particular, React paint validation walks only InstancedBufferGeometry.instanceCount; unused slack records are allocation capacity, not visible glyphs or paints.

Font delivery is an explicit benchmark axis. Baked asset exercises the normal sibling asset, while Runtime bake passes { source, runtimeBake }, downloads the source font, builds the core font in the serial core-baker Worker, then builds the selected Bitmap or MSDF raster in its serial lazy Worker. The inspector distinguishes the always-loaded runtime/shaper graph from the conditional core and raster baker host, Worker, and Wasm graphs; it reports source download bytes, generated core/raster CPU bytes, bake durations, and atlas GPU memory. The runtime-fallback conformance workload renders both delivery paths through the same public pipeline and requires an exact RGBA frame match. The headless conformance suite always runs baked delivery, so benchmark:runtime-fallback is the lane that exercises runtime delivery: canonical Inter matched exactly for Bitmap, MTSDF, and Slug on hardware WebGPU, each reporting 1/1 exact with zero mismatched bytes, zero changed pixels, and zero maximum error. The observed cold MSDF raster bake was roughly 114 seconds on this host and remains an observation, not a portability threshold.

The benchmark manifest exposes only build, dev, test, and check. Specialized maintenance files declare their own names, requirements, write behavior, arguments, and runner; the root pnpm scripts command validates and indexes that metadata. Vitexec can exit zero after an injected module or page failure, so the runner forwards and inspects its captured output and rejects [error] or [page error] records; focused negative controls prove both markers while ordinary logs remain accepted.[^workflow-runner][^workflow-output] An ordinary build consumes the checked-in canonical package-size record without rewriting it for the current host. release:size:generate is the sole writer, while the test gate measures the current host read-only and enforces the reviewed absolute and cumulative ceilings. benchmark:presentation runs every sequential workload through Bitmap, MTSDF, and Slug on WebGPU and forced WebGL2; benchmark:demo runs the timed sequence; benchmark:raster-comparison owns finite-job recovery; and benchmark:presentation-performance records the current complete cadence sweep. Closed milestone experiments and technique-specific performance matrices are retained as results, not executable product gates. The authenticated HarfBuzz freshness gate remains separate from ordinary repository checks because Meson, Ninja, and GLib belong only to that workload. Install the scoped apps/benchmarks/mise.toml pins when needed, then run pnpm scripts run fixture:harfbuzz:provision and pnpm scripts run fixture:japanese-showcase:check. React Doctor remains a manual review tool rather than a package or CI script; when requested, run mise exec -- pnpm --dir apps/benchmarks dlx react-doctor@0.7.2 . --scope full --blocking warning --verbose --no-supply-chain --no-color.[^presentation-framerate-sweep]

pnpm scripts run benchmark:demo exercises the complete 60-second timed sequence through a focused control on WebGPU and forced WebGL. Off-axis / 3D and Icon Grid each receive two seconds before Paint & Effects begins at second four; the more visual Zoom Text and returning Icon Grid scenes receive longer holds than Dynamic Layout. Advanced Shaping resets to CJK and reveals one complete five-case cycle at 180 grapheme units per second. Playing case transitions begin the next script at its first grapheme; a font-changing handoff deliberately blanks the live line until that generation commits instead of showing mismatched old-script state. Zoom Text pre-shapes all 16 fixed-Inter, language-tagged words during cold scene preparation and retains one node per word; animation performs only scale, opacity, and visibility changes, so it continues its normal word cycle without an animation-time readiness boundary and cuts after three complete default-speed drops. Text Ladder receives the derived 7.2 seconds required for its default-speed vertical travel and 1024 px marquee to pass completely through the left edge before the nine-second Icon Grid return. A final 8.016-second Off-axis / 3D scene supplies the closing frame. The probe requires window-capture Space handling, exact workload defaults after preload, advancing telemetry, a retained canvas, exactly one renderer, both Icon Grid entries, the configured backend throughout, and the final Off-axis / 3D scene.

The retained MTSDF live-text registry derives its artifact admission ceiling from the largest exact uncompressed byte length in the authenticated fixture manifest. This admits the 94,640,148-byte Amiri artifact used during the Advanced Shaping cycle instead of incorrectly applying the generic 64 MiB ceiling. Exact manifest length and SHA-256 verification remain mandatory before registration; the derived ceiling does not accept changed or unauthenticated bytes.

The Benchmark and Conformance tabs are named React 19.2 Activities. Each remembers its last selected workload and preserves its React state, while React disconnects effects for the hidden tree. Hiding Benchmark therefore runs the renderer cleanup that stops its animation loop, drains any active GPU timestamp query, and releases its renderer; hiding Conformance aborts any in-flight finite capture. Three's WebGL fallback deliberately loses its context during renderer.dispose(). Because an Activity preserves DOM while reconnecting effects, each mode transition changes the renderer-surface key and replaces the preserved canvas before a renderer can initialize again; reusing the lost canvas makes WebKit return null for SCISSOR_BOX and VIEWPORT, which Three passes to Vector4.fromArray. The exclusive lifecycle also waits for the actual webglcontextlost event before admitting the replacement renderer. Failed initialization releases any acquired WebGL context directly instead of calling Three's dispose(), whose internal async setAnimationLoop(null) would otherwise retry the rejected initialization promise and surface an unhandled rejection. Advanced-shaping playback is gated by the visible Benchmark mode because its coordinator lives above the Activity boundary.

The Vite build runs the pinned React Compiler preset and emitted production bundles import React's compiler runtime. The compiler optimizes the React tree; renderer identity remains an application responsibility. The benchmark application uses Koota only at its application boundary. Four coherent world traits own view, layout/workload, animation, and paint controls; a fifth owns the published telemetry snapshot. The world instance lives in a dedicated module so React Fast Refresh of component modules does not allocate a replacement world. The prop-free application child and root controller do not subscribe to live control or telemetry traits. Controls, layout, scene, and telemetry consumers observe only their coherent traits, while capture and renderer coordination read or update the world directly. Koota does not enter @pmndrs/text, shaping, layout, baking, raster packages, or their public contracts.[^runtime-world]

Main and Presentation are exclusive URL-selected root presentations. Presentation owns the scene and floating chrome directly: it does not render Main's header, workload rail, control aside, compact sheets, navigation, or hidden Conformance Activity. Each route owns one persistent render host, canvas, animation loop, GPU timer, and telemetry ring for its backend generation. Workload and technique changes activate a replacement scene while the committed scene continues rendering, then atomically swap and dispose the old scene resources; compatible font changes update retained Text objects in place. React Suspense owns genuinely cold asset loading, while scene selections are committed with useTransition after preloading so warm transitions do not replace the visible scene or reset the graphs. Runtime diagnostics and the live workload probe require one active renderer, one active canvas, and a peak concurrency of one through rapid presentation, workload, and technique changes. Main enters Presentation through one accessible expand-corners icon rather than a text label. Presentation's workload, font, and shaping-case selectors use the official shadcn Base UI Select; Base UI owns portal placement, outside-press dismissal, Escape handling, focus restoration, and keyboard listbox behavior, while the application renders selected human labels explicitly instead of exposing stored keys. A fixed left-edge viewport slot top-aligns one compact shadcn ButtonGroup, so workload-specific controls grow downward or scroll without moving the dock anchor. Each dynamic value owns a shadcn Popover: global GPU/GL and DPR selectors, workload sliders and toggles, Advanced Shaping selection/text/timeline panels, and MTSDF-only stroke/shadow controls. Informational descriptions and controls unavailable to the selected technique do not enter the Presentation dock. MTSDF paint starts with zero stroke and shadow disabled. One 1.5× presentation-scale boundary enlarges the top controls, telemetry, dock, and payload labels; inverse-scale viewport constraints, group-specific transform origins, and a 32 CSS px safe area keep every floating group clear of host-frame corners and on-screen without overlap at 1,280×1,280. Presentation surfaces use restrained shadcn-radius corners, plain 80%-black composition without a backdrop filter, and opaque borders. The graph rail owns one continuous background with opaque dividers instead of exposing translucent seams between child charts. Canvas render captions and navigation status remain Main-only. No visible exit action competes with the compact top-right telemetry stack, and Escape returns to Main. The comparison workloads retain framework-neutral Text objects behind the active presentation. Paint & Effects advances one circular per-word chromatic sequence directly on the renderer RAF through the synchronous paint-only batch path; shaping, paragraph layout, geometry, and React do not drive individual color frames. Its source span topology and update object are retained across animation frames, while Text retains the glyph-to-paint index plan. Animate, speed, hue, opacity, shadow, stroke, and layout-bounds controls mutate retained scene state and never enter the scene-rebuild path. Ordinary font-size and paragraph-volume changes may replace a generation because they alter glyph geometry or authored text. Resident layout-width, compatible viewport-width, font-size, font-fixture, and Dynamic Layout changes stage every affected Text, publish through Three.js matrix traversal, and reposition only after the complete synchronous lifecycle publication; ready remains a cold/error observation channel rather than warm control flow. Rapid controls pass through a latest-value serialized drain so obsolete intermediate values are never staged.[^comparison-workload] Live controls invalidate only an explicit capture, not the continuously updated typed-array telemetry, so metric labels and graphs do not disappear while a slider moves. Font selection retains the active benchmark shell and its last telemetry rather than showing an intermediate empty metric frame; comparison workloads additionally retain their canvas while the next font prepares. The live probe observes causal, monotonically increasing paint revisions, rejects layout work or batch replacement during paint updates, and proves comparison-workload font switching preserves canvas identity and never empties the CPU metric. Dynamic Layout stages all three paragraph reflows as one batch and positions the complete trio after lifecycle publication; it never recenters a mixture of old and new layouts. Neutral inspection frames remain default-on and share the same typed configuration boundary.

The maintained all-workloads live probe also owns the Presentation control smoke: it changes Icon Grid size through the retained popover, verifies outside dismissal and the human workload label, switches to Off-axis / 3D with zero missing glyphs, and checks the authored 200% layout-width ceiling. The former standalone control probe was removed so those assertions execute in the same real route sequence that already proves technique transitions and exclusive renderer ownership. Static dependency boundaries share one filesystem scanner, while exact renderer lifecycle, state restoration, and target-resolution behavior remain covered by focused executable tests rather than source-text assertions about function names or call spelling.

Every live benchmark identity resolves through one typed catalog under apps/benchmarks/src/workloads/. The catalog owns labels, descriptions, exact Main and Presentation defaults, font policy, controls and ranges, pan/zoom capability, preload policy, and surface kind; URL parsing normalizes an unknown workload inside its selected mode before font or control policy executes. Main and Presentation derive scene descriptions, amount labels, font selection, preload grouping, and pan/zoom capability from that authority rather than repeating workload-ID switches. Benchmark Ipsum and Advanced Shaping keep their authored corpus and timeline in the same workload hierarchy as Text Ladder, Zoom Text, Icon Grid, Off-axis / 3D, Dynamic Layout, Paragraph Stress, and Paint & Effects. They project their complete anchor, direction, feature, fixture, language, measure, text, alignment, glyph expectation, and timeline intent through the small LiveTextScene contract; the route only supplies runtime font size and selects a technique adapter. Advanced Shaping derives the font fixture from the authored case itself, preventing the displayed script and fixture from drifting. The seven retained comparison definitions own construction, layout, animation, and retained configuration hooks; no workload-specific dispatch switch remains for those phases. Icon Grid additionally owns one per-mount instance containing virtual-window epochs, pool assignment and recycling, scroll and auto-pan state, frame smoothing, refresh suspension, visibility, and metrics. The host exposes only generic cold pool resize/readiness, scene attachment, and disposal; renderer, canvas, RAF, GPU timer, font transactions, and telemetry history remain route infrastructure. Each workload mount explicitly initializes the shared scene transform, preventing Text Ladder's authored offscreen exit or Icon Grid pan from polluting the next workload. Their technique-invariant content-width, text-style, and color-cycle utilities live below workloads/shared; a source-boundary test rejects static or dynamic imports from any workload module back into renderer implementation files.

The root app.tsx owns only runner detection, shell Suspense, and URL route selection. Both route branches render the same routes/harness-route.tsx component type, preserving one runtime-world identity while controllers/harness-controller.tsx owns URL revisions, post-preload transitions, presentation playback, shortcuts, and execution state. Persistent renderer provisioning and exclusive conformance-action adaptation live in surfaces/harness/persistent-layout.tsx; Benchmark/Conformance scene composition lives in surfaces/harness/scene.tsx; Main and Presentation chrome remains in components/harness-layout.tsx; and runtime control binding remains in components/runtime-controls.tsx. The three persistent Bitmap, MTSDF, and Slug live-text viewport controllers live under surfaces/benchmark, keeping their host lease, synchronous update path, staged font-fixture loading, loading state, telemetry, and probe contract beside the rendered surface. Their renderer imports remain literal dynamic boundaries: type-only references use import type, so the production build retains separate technique chunks rather than pulling renderer implementations into the route entry. Authored scenes load fixtures through workloads/font-assets: one discriminated adapter selects only the requested Bitmap, MTSDF, or Slug lane through literal dynamic imports, while each lane loads its fixture exactly once through the target-v1 FontLoader from @pmndrs/text/three, using the public raster technique and @pmndrs/text/runtime-bake entrypoint. Baked delivery authenticates the artifact first and then publishes those bytes as a blob URL, because LoadedFontInput names URLs rather than bytes; runtime delivery passes the measured core baker as the request's runtimeBake. Because the loader registers into the registry the caller supplies, BenchmarkFontAsset.font is a projection of loaded.font rather than a second registration, and the retained merged-v0 raster module resolves the raster key the load already attached instead of baking again. Loads that name no registry share one THREE.LoadingManager, so their fonts share one text runtime as a paragraph batch requires; each caller-supplied registry keeps its own manager, runtime, and loader, preserving the ownership isolation those surfaces already had. The adapter owns source-font URLs, baked transport URLs, gzip and SHA-256 authentication, and runtime progress and delivery metrics; renderer modules retain only live GPU lifecycle, configuration, statistics, and compatibility delegates. Delivery metrics instrument the technique's runtime baker through a clone, which still renders because the Three program registry resolves programs by stable technique ID rather than object identity. Direct font-baker imports and Wasm URLs remain prohibited from this workload-facing path. Conformance React composition lives under surfaces/conformance: both the retained comparison and finite captures can receive only the host-owned renderer, while executable low-level work lives below benchmark/targets/conformance, benchmark/targets/product, and benchmark/targets/measurement. The realtime MTSDF/Slug comparison, runtime-fallback capture, external raster proof, React reconciliation target, and finite Bitmap/MTSDF/Slug product lifecycles are owned by those explicit target trees rather than renderer. The finite product targets accept the runner's renderer and abort signal, lazily load their public Text scenes, render deterministic frames, and dispose only resources they own. Shared Bitmap line construction, exact CPU-reference composition, renderer-state restoration, and RGBA8 readback normalization live below benchmark/low-level/raster; MTSDF and Slug product scenes remain target-owned because they are executable benchmark examples. Pure CPU raster and source-outline oracles live in the same low-level tree, so renderer-adjacent finite capture code can share primitives without importing executable targets; a source-boundary regression prohibits renderer-to-target dependencies. Advanced Shaping lives in the conformance target hierarchy behind the registry's literal selected-target dynamic import. Bitmap, MTSDF, and Slug conformance dispatch now enters technique-owned target modules rather than live renderer files. MTSDF and Slug sampling plus source-outline targets implement the same warm session contract, preserving load → capture → dispose reuse and forwarding the borrowed renderer and abort signal unchanged; Bitmap's thin target wrapper reuses its neutral low-level finite scene. The target modules own CPU comparison, renderer-state restoration, standard visual captures, and Slug role/external-resource proofs; renderer modules retain only live persistent-scene and font/configuration infrastructure. The targets share the explicitly named targets/shared/direct-wasm.ts dependency adapter only after target selection. The public missing-sibling loader Worker is conformance because it proves authenticated Worker bytes and loader fallback behavior; it is not a rendering product target. Boundary tests reject workload imports back into renderer implementation, reject renderer imports of executable targets, authenticate literal selected-target imports, preserve selected-technique asset chunks, and reject direct font-baker or Wasm URL imports outside the shared adapter, preventing raw tooling from leaking into the normal Presentation module graph.

The external raster product proof renders a competing transparent cover and public Text under different parent Groups on WebGPU and WebGL2. The external package's static policy and font binding run through the Rust command-buffer path; its renderer factory receives only plan-selected buffers. Framebuffer differences prove caller-owned Group order through actual Three.js sorting, while the baseline toggles public Text.visible to prove one indexed instance can disappear without splitting the shared draw or rerunning layout. Two samples per backend reproduce the same RGBA SHA-256 817495c4afe3a8f88d2af85d972f43be88b9f834ed0268d0d0b2e3de86ba9d46.

Timed playback compares each frame with the latest requested location rather than the last committed scene, so an in-flight preload receives exactly one request and cannot be superseded by a duplicate transition that skips workload-default initialization. Presentation captures Space at the window capture boundary to start or stop timed playback even while a button, switch, slider, select, or combobox owns focus; matching key-up activation is suppressed, while inputs, textareas, and editable text retain ordinary space entry. Arrow navigation remains disabled on interactive controls.

Icon Grid auto-pan integrates a bounded exponential average of observed frame deltas so a delayed display frame does not become a visually abrupt catch-up jump. This affects motion only: the virtual window still traverses the complete 1,402-glyph catalog, retains its overscanned pool, and requests content reassignment after crossing a complete cell pitch. Its second timed appearance, after Text Ladder, starts at a different catalog position and reverses both axes. The orthographic camera owns scrolling, leaving retained text transforms stable instead of invalidating every world transform through a moving scene root. Recycled strings are staged together and published once; nominal one-em icon-cell alignment avoids a synchronous layout query. Icon Grid telemetry reads draw and glyph counts from realized command-buffer geometry and never calls measureLayout, so observing the demo cannot trigger a second full-batch semantic query. Query-gated DevTools measures expose update, publication, and renderer-submit phases without entering customer builds by default.

Clean Chrome/WebGPU samples on the 120 Hz development display, after a server restart, reported Bitmap at roughly 116 FPS with 9.17 ms p95 and 16.59 ms p99 frame intervals, MSDF at 120 FPS with 9.23/16.65 ms p95/p99, and Slug at 120 FPS with 9.07/9.27 ms p95/p99. Median CPU submit time was 2.67/2.78/1.27 ms and median GPU time 0.85/1.05/3.74 ms for Bitmap/MSDF/Slug. These are host observations rather than CI thresholds. The core 684-paragraph, 200-cycle regression owns the sustained-retention gate that prevents the former status-7 failure and multi-gigabyte line-scratch amplification from returning.

Rapid Presentation controls compose against a requested-location revision rather than the last React commit, so a workload selection made while a technique preload is pending retains both requested changes and only the newest preload may commit. Retained Bitmap, MSDF, and Slug controls may arrive before cold scene activation; an activation gate releases them to a latest-value serialized queue, preventing animated text from starving layout completion. Bitmap's exact glyph assertion is committed with the workload instead of leaking from Benchmark Ipsum into Advanced Shaping, and zero-glyph intermediate generations are hidden from GPU submission.

Workload-local view state does not belong to the persistent renderer generation. Every workload transition installs its complete view, layout, amount, animation, and paint default snapshot; the outgoing Paragraph Stress RAF stops writing as soon as another workload is requested. The retained comparison scene atomically swaps the workload-appropriate orthographic or perspective camera with the prepared scene, resets scene pan, camera zoom, animation epochs, and virtual-grid cursors, and preserves those values only for same-workload edits. Text Ladder keeps its final 1024 px specimen visible during ordinary interactive looping; active timed playback alone enables the authored marquee exit so the scene can cut after the specimen clears the left edge. The sequential Presentation product probe operates the actual Base UI selector through all seven workloads, retains one canvas and renderer, rejects browser warnings, validates applied defaults and camera projection, and samples canvas identity, dimensions, renderer count, glyphs, and draws throughout each complete workload interval. After each capture-free interval, one headless DPR-2 framebuffer crop proves visible foreground pixels so nonzero telemetry cannot mask an off-screen or black result; avoiding continuous full-page capture also prevents Chromium's hardware-compositor screenshot path from flashing the observed canvas. The separate headful timed-demo probe performs no screenshots. The same workload probe is parameterized across Bitmap, MTSDF, and Slug. A requested screen grid with zero generated vertices remains hidden during the temporary 1×1 pre-layout surface, preventing an empty WebGPU draw warning without suppressing validation output.

Conformance uses the same route-owned renderer instead of allocating a parallel renderer. The realtime MSDF / Slug comparison is a retained host scene that restores render-target, clear, viewport, scissor, and automatic-clear state after each frame. Finite Bitmap, MTSDF, Slug, source-outline, and runtime-fallback captures run as exclusive borrowed-renderer jobs; their state transaction restores the host renderer after success or failure, and capture disposal releases only capture-owned text, font, raster, and render-target resources. Standalone capture callers retain the existing create-and-dispose behavior when no renderer is supplied.

Live CPU, FPS, and GPU telemetry share frame timestamps, one RAF-driven presentation clock, and one fixed eight-second display window. Its fixed typed-array rings derive frame slots arithmetically rather than allocating per-frame tokens or churning Map/Set entries. Empty GPU polls share one immutable result and chart drawing selects typed series without descriptor objects. GPU query polling remains backend-specific and asynchronous; resolved durations backfill their original frame slots while the most recent resolved duration forward-fills later slots. Renderer disposal awaits an outstanding WebGPU timestamp resolution before Three releases its buffers. The chart head is presented 250 milliseconds behind the current RAF timestamp so delayed measurements usually settle before their aligned CPU/FPS/GPU position becomes visible. This is display latency only: it does not delay rendering, alter samples, add timers, or make benchmark measurements synchronous. The FPS series applies a 250-millisecond time-based exponential average to frame duration before converting it to a rate, reducing reciprocal clock jitter while preserving the unsmoothed CPU and GPU timings and the observed refresh-rate ceiling. Typed histories continue to update on every renderer RAF, while the Koota telemetry trait publishes a new React-facing summary only at the configured 250-millisecond report boundary. Controls, scene evidence, shell metrics, and Presentation overlays share that trait; the root application does not receive per-frame stats or prop-drill them through the tree. CPU frame timing begins at the renderer callback entry and includes completed-query polling, workload animation/update, and render submission. It does not claim React/browser work scheduled outside that callback, swap-chain presentation, compositor work, or time waiting for the next RAF; FPS remains the wall-clock pacing signal. Vite development and preview responses carry Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp, making the benchmark cross-origin isolated so Safari does not reduce these CPU measurements to whole milliseconds. All runtime fonts, Wasm modules, and module Workers are Vite-owned same-origin resources; remote fixture downloads remain offline maintainer workflows.

The responsive shell reserves the three-column rail/main/control layout for viewports at least 1,200 CSS pixels wide. The wordmark toggles the workload rail at desktop size and opens the workload drawer below desktop. Main mode keeps technique selection above independently scrolling workloads and presents font fixtures as buttons below them. The fixture panel remains content-height when its buttons fit, grows only as they require, and caps at half of the post-Technique rail region; only then does its button list scroll with the same contained overscroll and directional edge fades as the workload list. Compact Main controls use the same fixture buttons, while Presentation keeps its intentionally compact custom dropdown. Tablet and phone keep the live scene mounted, carry the shared Bitmap/MSDF/Slug switcher in a compact header with explicit separation between techniques, and present controls as a scrollable floating panel capped at 60% of viewport height; they do not replace the scene with a bottom-tab flow. Form controls inherit only the design-system font family, leaving their explicit Tailwind size and line-height utilities authoritative. The scene header stacks before its chips on narrow widths, and control labels stay at or below 13 CSS pixels without clipping while interactive controls retain at least 28 CSS pixels of height. Shared range controls remove text-field padding and draw their visible rail exactly one half-thumb radius inside each edge, so the minimum and maximum rail endpoints equal the native thumb-center travel. An accent segment fills from the minimum to the controlled value over the remaining neutral rail. Component tests distinguish range and text geometry, normalize and clamp fill progress, and the live product probe verifies zero horizontal padding, the explicit inset, visible fill/rail layers, and both numeric endpoints. The responsive product probe owns technique switching, drawer and panel interaction, retained-scene visibility, the 60%-height panel cap, and horizontal-overflow gates at 390, 1,024, and 1,280 CSS pixels; its in-process Vite lifecycle resolves the compiler from the application workspace, selects an available local port, and closes both browser and server after success or failure.

This application owns the shared target/scenario runner, responsive Figma-backed interface, URL state, validation/report/export views, deterministic synthetic target, real portable-baker target, real public loader/Worker-fallback target, real HarfRust shaping-conformance target, real paragraph measurement/positioned-layout/policy/CJK targets, the dual-backend TSL shader baseline, the public Text bitmap target, and the public React Text reconciler target. The TSL baseline now uses a green decoy record plus a u32 logical-order table selecting a red physical record, so its exact readback proves the nested storage lookup used by stable-indirect plans rather than only proving a constant node graph. Forced WebGL2 and hardware WebGPU both return 16/16 red pixels with hash fec0f57d…c77. The runner disposes partial target state when loading fails, and the UI retains typed WebGPU availability through label and tone rendering. The interactive UI, browser headless CLI, Vitest, Vitexec, and Playwright all call the same strict registry execution module. Inter 4.1 remains the default fixture; Amiri 1.002 owns complex-script evidence; Noto Sans CJK JP 2.004 owns the maximum-cardinality universality lane. Each is immutable, licensed, hash-authenticated, and paired with checked HarfRust/HarfBuzz evidence. Chromium 149 runs the bounded conformance suite through forced WebGL2, including exact bitmap readback and deterministic React reconciliation; the maintainer-local lane repeats the bitmap frame on hardware WebGPU. The CJK result fixes thirteen corpus cases, four paragraphs, twelve layouts, eight plans, one direct shape call, four paragraph shape calls, zero reshapes, 10,622 output bytes, and the exact composite hash a1a833f2:fbe2aa07:922f9a2e:8c977f4d:85a2f640:fd42b9f7:53d8ec89:8cb3050c:bbfd039d:837a2b43:2f450f5e:9900b4af:c49f3e68; Vitexec repeats it with WebGPU active.

Milestone 9 adds deterministic package-owned Slug GLB fixtures for all seven visual families and one copied-and-adapted Three.js/TSL benchmark adapter. The fixtures compose the shared core artifact with embedded analytic curve, exact header, and exact reference resources, authenticate raw and gzip identities, and publish bake plus decoded-GPU totals in one checked manifest. The adapter supports baked and serial runtime delivery, reports curve/header/reference allocations separately from the framebuffer, and exercises the public Slug raster through the same retained Text, dual-backend renderer, frame readback, and live telemetry boundaries as the established raster targets. Slug is a genuine third technique across all seven live comparison workloads, the independent CPU sampling comparison, source-outline fidelity, and baked/runtime parity surfaces. Its imports remain dynamic so selecting Bitmap or MTSDF does not load Slug. Deterministic WebGPU and forced-WebGL2 product, sampling, and source-outline probes pass. The shared hardware-WebGPU product probe covers Bitmap, MTSDF, and Slug over Text Ladder, Zoom Text, Icon Grid, Off-axis / 3D, Dynamic Layout, Paragraph Stress, and Paint & Effects. Paint & Effects limits Slug to animated fill and opacity and disables both outline and shadow controls; MTSDF retains both effects. The retained quality and performance matrices use authored Latin, Arabic, Devanagari, and Japanese specimens instead of sending every font through Latin fallback. The packed-hull experiment retains exact dual-backend quality, timing, payload, and residency evidence but is rejected and removed from the shipping tree because no source clears the performance gate on both backends. The root-contribution experiment likewise retains its precommitted manifest, complete 28-cell quality result, final-program identities, and 140 paired sessions while removing its temporary graph selector and probes. All pixels and resources remain exact. Final Three programs prove that the baseline already lowers select to eight root-condition branches across both axes, while the candidate coalesces the same work into four but adds 304 generated bytes on each backend. No source clears 5% on both backends: median paired deltas across the seven sources are +0.84% on WebGPU and -1.56% on WebGL2, with an 8.43% CJK WebGPU regression and 11.22% Inter WebGL2 regression. The applicable older-fork baseline and retained challenger queue are complete for Milestone 9; new hypotheses remain future measured research.

The fully external release gate freshly bakes canonical Inter into five files: one core GLB, one Slug companion, and separate curve KTX2, header, and reference resources whose roles, lengths, and SHA-256 identities are retained. Public FontLoader preserves URL/fetch provenance and public Text renders all-external resources byte-identically to the embedded fixture: hash f879dd9a…b4ecf on WebGPU and b34a6866…bed0 on forced WebGL2. Both forms evaluate 84 glyphs and 470,202 curves. The request log requires one fetch each for the core and companion and two each for the three page resources because public Text and the independent CPU-reference decode consume them separately; the capture removes its transient bake directory in finally.2

The Zoom Text workload fixes its font identity to the authenticated Inter 4.1 fixture because the repository has no universal Noto Sans raster trio; its Noto CJK fixture is an intentionally incomplete 155-glyph showcase subset. Sixteen unique noun translations of “Shape” cover English, French, Spanish, German, Portuguese, Polish, Turkish, Greek, Russian, Ukrainian, Vietnamese, Icelandic, Romanian, Welsh, Serbian, and Kazakh across Latin Extended, Greek, and Cyrillic. Every scalar is present in the hash-authenticated Inter source. One session order is created when the module loads: English Shape remains first and a Fisher–Yates pass permutes the remaining unique strings without replacement, shared by Bitmap, MTSDF, and Slug. Every language-tagged Text is shaped once before publication. Exactly one centered entry is visible, and its retained object transform follows a cosine cycle from 8 pt (10.67 CSS px) to the largest word-specific scale that fits the current viewport; phrase identity changes only at the minimum-size boundary. Resize recomputes each committed layout's center and fit bound without shaping, reflow, or pan. Live WebGPU and forced-WebGL probes cover Bitmap, MTSDF, and Slug with one draw, zero missing glyphs, one initial text-update sample, zero animation reflows, and stable retained configuration while scale and language advance.

The Icon Grid workload adds the complete licensed Font Awesome Free Solid 6.7.2 catalog as 1,402 named glyphs through Bitmap, MTSDF, and Slug. It lays the catalog out on one 38-by-37 two-dimensional coordinate plane, keeps labels centered at a fixed 11 CSS pixels, scales icons logarithmically from 8 to 1,024 CSS pixels, and supports pointer panning in both axes. A viewport-sized pool with three overscan rows and columns recycles only after replacement content is ready, preventing partially updated slots from flashing during pan, resize, or font replacement. Overscan assignments remain warm for recycling but only tiles intersecting the exact viewport are visible to Three's render traversal. Static tile, icon, label, and generated-mesh local matrices are updated when their layout changes and otherwise opt out of per-frame local matrix recomputation; the panned scene transform remains dynamic. Each pooled tile owns separate icon and label Text generations: icon-size changes regenerate only the one-glyph icon batches, preserve the fixed-size label generations, and grow or shrink the existing pool incrementally when viewport coverage changes instead of replacing the complete scene. Each visible tile still submits its icon and label as separate draws; renderer-level batching across compatible independent Text objects remains future work rather than an application-local special case. Closing a comparison workload stops its renderer loop before draining outstanding text work, so a hidden or replaced scene cannot keep submitting background frames. The retained product probe reaches icon 1,401 and returns to the origin with zero missing glyphs for all three techniques; at the standard probe viewport it uses 143 pooled entries rather than retaining the entire catalog. The icon font and label font share one registry but remain separate registered fonts, exercising the public multi-font renderer boundary without introducing a React-only registry abstraction. The workload's fixture controls expose only the packed Font Awesome icon font; the fixed label family remains implementation metadata. Live DOM evidence, captures, and reports identify Font Awesome as the primary icon fixture and the selected family as the label fixture; payload and GPU-resource totals include both fonts rather than attributing the combined scene to its labels alone.

The retained release-role matrix adds 36 focused Chromium 149 observations: six large-size, extreme-scale, complex-script, and viewport-clipping scenes plus one copied-and-adapted affine transform and one same-geometry 1×/8× projection-zoom scene, repeated at DPR 1 and 2 through WebGPU and forced WebGL2. Flat scenes compare the candidate with both the independent scalar Slug sampler and the current browser's source font; transformed scenes use the source font as visual authority and explicitly mark a transformed scalar oracle as not applicable. Three Flatland revision 2935a89f… supplies historical transform and zoom invariants only. Candidate hashes are exact across DPR within each backend, clipped scenes touch the physical viewport boundary while unclipped scenes do not, and the centered Inter I retains a measured one-physical-pixel partial-coverage fringe at both zooms. This evidence proves host viewport clipping under the current renderer boundary; it does not claim the older toolkit's arbitrary per-instance clip-plane API.

Roadmap item 6.0 uses only WebGPURenderer and the public three/webgpu plus three/tsl exports for runtime values and types. App lint rejects the legacy root, internal source paths, addons/examples paths, and bare R3F entry so this boundary cannot silently drift. Direct calls to installed public scalar TSL operators keep clean TypeScript 7.0.2 checks below one second; vector/scalar overloads and method chains remain measured recursive-expansion hazards. A repository-owned @types/three patch gives modelViewProjection its runtime Node<'vec4'> type, with a compile-only regression until the correction is upstream. The same graph produces the exact SHA-256 fec0f57de0b19bc7dacb5b0fc3de7b56fc68dfdbeeebc8f9f4c506bf6e821c77 through an asserted WebGPU backend and forced WebGL2 fallback, three measured runs each after one warmup. The oracle rejects any non-red pixel, carries an intentional wrong-pixel negative control, and compacts the 256-byte row alignment retained by Three.js's WebGPU readback before comparing it with WebGL2's compact bytes. This is a real dual-backend shader workload, but the synthetic plane is intentionally not mislabeled as the first rendered font frame; item 6.1 owns that claim.

The application's browser and script projects use the repository-pinned TypeScript compiler directly. Compiler-sensitive TSL changes begin with the package's focused NodeExtras regression before expanding to this complete application; the patched declaration graph keeps the benchmark project below 300 MiB on the recorded validation run without a process guard.

Every measured call receives its actual zero-based sample index; warmups remain outside the reported sample sequence. Controls reject invalid sample/warmup counts and non-finite, non-positive, or greater-than-4 DPR before target loading. The existing 1×/2× scene buttons now select the actual renderer density, initialize from the user's display class, and invalidate stale results. Automated probes and the headless CLI always pass DPR explicitly. Successful summaries include the V0 schema marker and exact controls, so timings, framebuffer bytes, and pixels cannot be compared without their density. The deterministic headless lane runs its cases sequentially through one Chromium/Vite session while opening an isolated page for each case; explicit readiness, launch, navigation, and execution deadlines identify a stalled lifecycle without using time as a readiness signal.

GitHub CI uses the Ubuntu runner's rolling system Chromium as a deliberate compatibility canary instead of downloading Playwright's pinned browser. The workflow discovers an executable, prints its version, fails if none exists, and exports only PMNDRS_TEXT_CHROMIUM_EXECUTABLE_PATH. One shared launcher conditionally supplies that exact path to all five direct Playwright launch sites; without the variable, local commands retain Playwright's managed executable. Every launch reports browser.version() to stderr, and headless benchmark summaries retain that exact value as browserVersion beside the browser-provided user-agent string, whose Chromium minor/build components may be reduced. The packed-tarball consumer declares a data-URL favicon so its synthetic document makes no browser-implicit network request; browser error diagnostics retain console source locations and failed HTTP status, resource type, and URL. Historical fixture filenames and goldens remain tied to their recorded captures rather than being relabeled by this rolling lane.

The canonical package-size lane measures the initial public JavaScript graph, lazy font validator, runtime Worker boundary, baker and shaper JavaScript/Wasm, Unicode 17 analysis, and representative font artifacts without zero-byte placeholders. Static entry closures and dynamic chunks are separated from Rollup metadata rather than conflated; Core JS externalizes the package's declared Three.js, React, and R3F peers, and package-owned Wasm URLs are externalized from JavaScript measurements regardless of their owning package. The detailed record retains its measurement platform, architecture, SHA-256 payload identities, and reviewed raw/minified/gzip/Brotli ceilings because those fields enforce reproducibility and detect internal regressions. The human summary is deliberately smaller: the benchmark UI and Size Limit pull-request comment use one fail-closed projection containing only gzip for Core JS, Shaper Wasm, Three.js adapter JS, Inter plus Font Awesome across Bitmap, MTSDF, and Slug, and each optional validator, runtime-bake, font-baker, and raster-baker JS/Wasm payload. It publishes neither arithmetic runtime/delivery totals nor alternate compression columns. This keeps each displayed number attributable to one emitted payload and avoids presenting external peers or a chosen font combination as a universal application total. The inspector's runtime and resource cards remain separate workload telemetry rather than inputs to the pull-request size summary.

The current Darwin arm64 record reports a 66,839 minified / 18,659 gzip / 16,177 Brotli peer-externalized browser graph and an independently measured 141,103 / 42,399 / 31,307 Unicode analysis graph. The validator, runtime host, initial runtime Worker, font-baker host, font-baker Wasm, and shaper Wasm report 583,452 minified, 14,291 minified, 613,017 minified, 7,940 minified, 1,097,702 raw, and 1,159,317 raw bytes respectively. Their gzip sizes are 137,404, 5,506, 145,805, 2,471, 391,576, and 442,284 bytes. Bitmap, MTSDF, and Slug baker hosts measure 4,767, 5,516, and 4,111 gzip bytes; their Wasm modules measure 234,736, 215,027, and 186,664 gzip bytes. Static Node project discovery is excluded from the direct font-baker host graph, and dynamic raster modules are excluded from the initial Worker graph because each has its own independently visible row. Bitmap-only and MTSDF-only size entries inspect their initial module closures and fail if Slug runtime, shader, baker, or runtime-baker modules enter either graph. Paragraph layout hashes and the policy composite hash share one implementation over the actual normalized layouts; the generator, benchmark target, unit tests, and Vitexec probes no longer maintain parallel digest logic.

The local Worker-queue Vitexec probe authenticates every output and reports observations rather than asserting machine-sensitive timing. Two Chromium runs measured a three-font queued burst at 30.8–32.0 ms and three separately initialized sequential Workers at 68.3–88.6 ms. The correctness suite separately proves one active post, FIFO completion, queued cancellation, and active-cancellation recovery without timers. The combined live lane runs its performance observation before interaction and conformance probes so accumulated renderer work cannot contaminate cold/steady telemetry.

Item 6.1 replaces the bitmap placeholder with the harness's first real rendered font frame. A checked-in composed Inter GLB loads through the public registry, shapes and positions the five-line diagnostic specimen through HarfRust and the paragraph engine, decodes its embedded R8 KTX2 pages, and renders 120 visible glyphs in one instanced draw. The separate paragraph-scale live workload renders 1,151 glyphs in one draw. Public font size is logical CSS geometry: changing 1×/2× DPR does not resize a paragraph. The integration supplies rasterPixelRatio; bitmap targets CSS size × ratio, selects the nearest declared physical strike, and exposes selected ppem plus the resulting quality ratio. Every representative fixture now carries independent 16 and 32 ppem strikes: 16 CSS px selects 16 ppem at 1× and 32 ppem at 2×, while the inspector reports each strike's transfer and GPU residency separately. The screen-space ladder always spans 8–1024 CSS px. Live canvases are opaque and render the design-token background themselves. The optional 16 CSS px grid is one screen-space opaque mesh rebuilt only on resize, so text transforms, panning, DPR, and font scale cannot move or rescale it; grid-off skips that draw rather than exposing a compositing layer behind the canvas. Report capture disables the inspection grid before collecting timed evidence, so the decorative pass cannot contaminate benchmark samples.

The live telemetry loop owns one 1,024-frame, fixed-capacity timestamp ring shared by CPU submission, FPS, and GPU duration. CPU and FPS advance on every renderer RAF and never wait for a GPU query. WebGPU enables Three's timestamp-query feature and attempts one asynchronous resolution whenever the prior resolution is complete; Three's resolved renderer-frame identity maps the result back to the corresponding application frame. Every frame receives the most recently resolved GPU duration immediately, and a newer resolution retroactively refreshes the still-pending frame slots, matching three-flatland's sample-and-hold model instead of drawing a lower-resolution sparse series. The product calls its fallback backend WebGL; internally that backend owns an EXT_disjoint_timer_query_webgl2 query per frame on its WebGL2 context, polls QUERY_RESULT_AVAILABLE and GPU_DISJOINT_EXT on the renderer RAF, and discards disjoint results. Neither backend creates a timer or a second animation loop. Unsupported timing remains visibly unavailable and is never replaced with CPU submission time. React summary publication stays bounded, while the three canvases read the mutable rings on one shared presentation RAF. Their common eight-second timestamp window scrolls continuously at display cadence without interpolating or reshaping measured sample heights. FPS retains numeric precision internally but renders as whole frames; millisecond metrics retain fractional precision. Quantiles and observed extrema scan finite retained samples with preallocated scratch storage.

The graph surface owns one animation frame for all three canvases. It reads the aligned cursor directly and paints FPS, CPU, and GPU at identical timestamp-derived x coordinates. FPS uses an ascending fixed 0..refreshRateHz domain, placing zero at the panel floor and the estimated display rate at the top; CPU and GPU share 0..(1000 / refreshRateHz) milliseconds, so a missed display budget reaches the same vertical limit in both time graphs. Browsers expose no standard normal-display refresh-rate property. After an eight-sample warmup, the estimate uses the 25th percentile of the retained RAF periods so dropped frames do not lower the ceiling and a single short startup interval cannot permanently push a 60 FPS line toward the floor. Until then it uses 60 Hz. Each current value appears immediately beside its compact label, while the same-tone observed minimum–maximum range remains at the top right. Sub-centisecond nonzero values are reported as <0.01 ms, and the canvas fills its cell so the fixed zero domain maps to the visible panel floor. The backing stores still use each graph's fractional CSS bounds and physical display density, then draw through the exact rounded backing-store scale. History collection and drawing do not grow arrays, shift elements, build SVG strings, rerender React per frame, or use independent chart clocks. The live scene keeps the three wider graph cells beside equal, narrower glyph/draw and missing-glyph cells.

The application shell is fixed to the dynamic viewport and disables document scrolling plus scroll chaining. Desktop, tablet, and phone pass one definite remaining height through the active scene, benchmark surface, and realtime viewport; the canvas therefore expands or contracts instead of forcing the page taller. Workload rails, controls, reports, exports, and compact sheets own their local scrolling with contained overscroll, while the page itself remains stationary above the phone navigation.

The user-requested captured report owns renderer initialization, font registration, core/raster bake, text readiness, first-submit, upload-completion, first-GPU-frame, total-startup, artifact, and retained-GPU details. The right panel exposes rendered device size and proportional layout width; a changed content box commits a real paragraph reflow through the retained public Text object, while camera-only viewport changes retain the committed layout. A separate benchmark-owned fixed-capacity sampler measures synchronous text-update scheduling, combined public Text.ready work (font cache resolution, shaping, layout, and raster batches), application scene update, and total elapsed time without adding profiling code or branches to the shipped library. Captured reports present P50 and P95 update, CPU-frame, and GPU-frame costs with explicit update and frame sample counts. Live capture copies the frame rings only at the user-requested snapshot boundary and records the browser environment. Runtime-delivery paths additionally consume the public structured bake-progress channel: a determinate overlay remains visible from queue admission until the new font is committed, and development-console output is coalesced to phase changes and ten-percent buckets. The committed causal live probe proves timestamp samples and clean renderer replacement across WebGPU → forced WebGL2 → WebGPU without sleeps or retries.

The bitmap baker now retains Zeno's actual integer mask placement with planeUnitsPerEm equal to the strike ppem, rather than stretching the integer mask over analytic outline bounds. The TSL vertex graph snaps projected quad edges to physical framebuffer pixels. The shared target now constructs the public framework-neutral Text object rather than maintaining a second paragraph/shaper/batch path. A benchmark-only CPU compositor independently places authenticated atlas texels and must match every byte after WebGPU row-padding and WebGL row-origin normalization for both the full frame and a resized clipped frame. A one-quarter-device-pixel unsnapped object origin proves the snap is exercised without ambiguous half-tie rounding through the nested object transforms. WebGPU and WebGL2 agree on the complete frame: hash a47930d3…e893 at 1× and 95b20e05…a34d at 2×, with 3,473 half-coverage pixels at each density and respective bounds [68, 18, 313, 112] and [260, 82, 505, 176]. Framebuffer bytes are 196,608 at 1× and 786,432 at 2×; total tracked bytes are 891,904 and 1,481,728. Determinism, zero missing glyphs, exact strike/scale, CPU/GPU equality, full-frame boundary rejection, resized clipping, empty-output rejection, draw count, and GPU-memory contracts are hard gates. Hinted grayscale and four-phase coverage packing are documented research; LCD/ClearType rendering is out of scope. Bitmap and Slug support fill/opacity and reject outline/shadow explicitly. MTSDF owns scalable fill, opacity, bounded outline, and hard shadow.

Benchmark mode exposes the same seven specialized workloads for Bitmap, MSDF, and Slug: Text Ladder, Zoom Text, Icon Grid, Off-axis / 3D, Dynamic Layout, Paragraph Stress, and Paint & Effects. Benchmark Ipsum and Advanced Shaping use the same bounded-content policy through their technique-specific renderers. Screen-bounded paragraphs preserve an explicit authored minimum width on narrow canvases, where the existing pan interaction reveals overflow, then expand inside a shared 24 CSS-pixel viewport inset. A resize updates the surface and camera immediately but reshapes only when the resolved content width changes. Off-axis / 3D authors one continuous paragraph, starts at the viewport-neutral 100% content width, and exposes a distinct 40–200% control in both Main and Presentation. The control therefore owns wrapping and can extend the line beyond the viewport before perspective projection instead of preserving forced line breaks. Text Ladder and Icon Grid retain intrinsic world geometry and pan rather than fitting; centered Zoom Text deliberately retains its specialized no-pan viewport-fit behavior. Icon size remains a logarithmic zoom control over the grid while labels stay at 11 CSS pixels. Scaling remaps the fractional grid row and column under the viewport center into the new non-uniform tile pitch, so the icon being inspected remains centered unless an outer grid boundary requires clamping.

Grouped workload changes reuse one TextGroup and replace its children in one retained Rust publication, avoiding a second set of session arenas while the outgoing command buffer is live. Stale stats no longer erase an update failure, and non-abort failures reach the browser console. Draw/glyph telemetry traverses the realized batch root once because Rust-planned meshes are siblings of authored entry nodes; the complete performance sweep rejects every zero-glyph or zero-draw cell. The current 27-cell WebGPU sweep completes every Bitmap/MTSDF/Slug transition. It also makes the remaining Icon Grid gap explicit: 2,926–3,021 glyphs currently produce 476 draws and 30.8–47.0 RAF FPS even though median submit is 0.27–0.76 ms and median GPU work is 0.57–2.02 ms. That is batching-policy evidence, not a shaping-performance result or an accepted release cost.[^presentation-framerate-sweep]

Paragraph Stress can opt into Chrome User Timing with ?textTimings=1. Its retained update is split into authored property staging, Rust update plus demanded measurement, clean publication, renderer submission, and the package's internal Three phases. The production path performs no timing calls while the option is absent. The workload now asks for layout metrics before explicit scene publication, so the semantic mask shares the pending mutation and the later matrix traversal sees clean Rust state. Icon Grid constructs its batch with independent compositing; other workloads retain ordered semantics.

An identical direct Chromium 149/WebGPU/DPR-2 Paragraph Stress comparison retained 11,510 glyphs, one draw, and 64 authored reflows in every case. The committed baseline measured 14.295 ms median reflow; measurement piggyback alone on that baseline measured 13.615 ms; adding semantic dirty tiers while retaining the same old Rust measured 7.450 ms; the complete candidate measured 6.885 ms. These telemetry histories contain 13–16 settled samples and establish direction and isolation, not a portable frame-time gate. A normal phase capture attributes most changed-frame CPU time to the single Rust text_update; TypeScript preparation, semantic readback, plan application, and renderer submit are smaller. A symbol-preserving diagnostic did not provide honest finer Rust attribution because LTO inlines most warm work into the export, so internal phase timers are required before claiming a particular Rust loop is dominant.

Paint & Effects is one live paragraph whose per-word hue advances continuously; opacity is shared, bounded white outline and hard shadow are MTSDF-only, and Bitmap plus Slug disable both controls. Paragraph Stress treats text volume as a topology change: moving its volume control immediately rebuilds the repeated corpus, while controls that only alter retained animation or paint state avoid replacement layouts. Dynamic Layout derives its initial three phase-offset widths from the same elapsed animation clock as subsequent frames, awaits every paragraph layout, and publishes the trio atomically; the first visible frame therefore continues directly into animation instead of flashing a uniform-width staging layout. One benchmark-owned interaction component gives navigable live canvases mouse drag and two-finger touch pan; Off-axis additionally enables pinch and wheel zoom. It translates gestures into renderer-neutral view commands and does not put DOM listeners in @pmndrs/text. Workloads are deliberately not React Activities. They are framework-neutral retained scenes behind the route-owned render host, so a swap releases the old scene's text and font/raster residency without replacing the host canvas, renderer, timestamp timer, or telemetry history. Only the Benchmark and Conformance modes retain React state as Activities. The shared multi-technique workload implementation remains a dynamic chunk; Benchmark schedules a cancellable no-timeout idle import, while pointer hover or keyboard focus warms it immediately. Unsupported idle-callback hosts simply retain interaction warming, so the chunk never enters the initial graph and ordinary Benchmark startup never waits for it. The host serializes scene activation and retains the current scene until its replacement is ready, preventing an asynchronously initialized workload from publishing partial text or inheriting the prior workload's configuration. Renderer-published configuration revisions make product probes causal rather than reflections of React props. Dynamic layout separately reports one completed three-paragraph reflow cost and count instead of hiding reshape work inside the CPU-submit graph. The MTSDF base-level scene and sampling paths require deterministic pixels within each renderer invocation, authenticated artifacts and resource counts, and bounded error against the independent scalar reconstruction. Hardware Apple Metal and headless SwiftShader framebuffer hashes remain labeled observations because filtered analytic coverage is not byte-portable across drivers. The current SwiftShader comparison reports 0.0957/255 mean absolute error, maximum error 10, and 3,233 pixels above its threshold, all inside the reviewed 0.25/255, 48, and 2% envelopes. The current direct WebGPU observation reports framebuffer hash 4da56d…, 14,400 changed pixels, 2,420 colors, and a 6,798,412-byte compressed artifact; its scalar comparison reports mean absolute error 0.0184937, maximum error 1, and zero threshold error pixels. The gate names base-level behavior rather than the removed generated-mip path.

Cross-technique fidelity is the final conformance workload. It renders the selected Bitmap, MSDF, or Slug candidate through the real public Text pipeline, then independently rasterizes the same pinned source TTF/OTF, authored lines, physical size, direction, and paragraph baselines through browser Canvas2D. The synchronized candidate/reference/difference panels share pan and zoom. Chromium 149 WebGPU records canonical Inter at 7.393 mean error and 5,852 pixels over 2/255 for the native 16-device-pixel Bitmap strike, and 6.884 / 19,326 at the MTSDF 64-device-pixel base level. The retained Slug matrix covers all seven font sources at DPR 1 and 2 through both renderer backends: its independent analytic CPU comparison records mean error from 0.0032 to 0.0838/255, zero severe pixels for every ordinary outline, and 27–54 severe pixels for DotGothic16's grid-aligned pixel outlines. Ordinary Canvas comparisons retain the 12/255 mean gate; DotGothic16 has a separate 24/255 pinned-browser envelope because Canvas applies a materially different hinted pixel-style raster, while its analytic comparison remains bounded to at most 64 severe pixels. Every source retains the common 20% over-tolerance-pixel gate, and unit negative controls prove the ordinary and pixel-style envelopes fail independently. Canvas2D is a pinned-browser source-outline reference, not a claim of cross-browser bit identity, while the separate pipeline-accuracy cases continue to own exact Bitmap reconstruction and scalar MTSDF/Slug sampling.

The committed raster performance observation uses the live Paint & Effects workload at explicit 1× DPR on Chromium 149 and Apple WebGPU. A preflight draw separates CPU submit, wall-clock upload-frame completion, and the timestamp-query duration of the render pass; twelve later causal reports establish steady CPU/GPU values without readback or conformance work. The recorded Bitmap/MTSDF/Slug observations respectively measured 24.0/28.3/11.4 ms first-draw CPU submit, 27.6/46.3/18.1 ms upload-frame completion, 0.065/0.063/0.242 ms first render-pass GPU time, 0.3/0.2/0.2 ms median steady CPU submit, and 0.344/0.158/0.333 ms median steady GPU time. Slug's same-workload record contains its 618,487-byte compressed artifact and 3,162,112-byte analytic GPU allocation, split into 2,097,152 curve, 376,832 header, and 688,128 reference bytes. Upload-frame completion deliberately includes compilation, queue completion, and timestamp resolution rather than pretending browser WebGPU exposes an isolated texture-copy timer. These are environment-labeled observations, not portable budgets. The same record embeds exact isolated size entries for browser core, shaper Wasm, all three raster runtimes, and all three unloaded optional baker Wasm modules so performance evidence cannot hide bundle composition.

The Slug-specific 1,500×950 Text Ladder matrix retains twelve raw causal CPU/FPS/GPU reports for all 28 backend/DPR/source combinations. Every authored specimen renders zero missing glyphs, 810–2,160 analytic glyph instances, and eighteen draws. Across this Apple/Chromium observation, median CPU submit spans 0.4–0.8 ms; median GPU time spans 0.310–3.194 ms; startup spans 46.5–263.0 ms; compressed artifacts span 96,145–3,639,781 B; and analytic curve/header/reference residency spans 376,832–21,970,944 B. WebGPU's DPR-1 median GPU range is 0.310–1.120 ms and DPR-2 is 0.755–2.972 ms; forced WebGL2's corresponding ranges are 0.507–1.209 ms and 1.042–3.194 ms. Different specimens and source payloads make this a guard matrix, not a claim that font families are interchangeable microbenchmarks. The raw histories and exact resource components establish the immutable baseline for interleaved prior-art optimization challengers.

The removed Slug outline benchmark established why the feature is absent rather than a supported slow mode. Its 268-glyph Inter scene measured outlined totals at 2.44×–4.33× fill-only GPU time across WebGPU/WebGL2 and DPR 1/2. The benchmark-specific CPU stroke oracle, capture scripts, generated shaders, and retained result payloads were deleted with the runtime; the outline research record preserves the mechanism, summarized measurements, external evidence, and replacement gate.3

The first retained challenger doubles every glyph from 16 to 32 bands without changing the format or shader. All 28 quality cells remain byte-identical and scalar traversal falls by 12.0–19.4%, while five-round DPR-2 A/B observations show median GPU changes from −5.3% to −10.4% across Inter and the Japanese showcase on both backends. Fixed 32 is calibration rather than a production policy: gzip grows 14.4–21.6%, Slug GPU residency grows 13.0–20.3%, and Japanese WebGPU pairs cross zero. The retained artifact generator, raw runs, exact hashes, and result note make adaptive per-glyph bands the next bounded challenger instead of silently accepting a universal memory trade. A precommitted {16, 32, 64} policy targeting at most six mean references per band is rejected before GPU measurement: it escalates too many glyphs to 64, grows gzip by 9.7–30.2%, and grows residency by 8.6–25.0%. Its exact artifacts and glyph-count distributions prevent the failed threshold from being rediscovered. A separately precommitted {16, 32} cap preserves all 28 exact quality cells and lowers scalar traversal 2.7–13.5%, but adds 6.5–17.0% gzip and 5.7–14.6% runtime residency. Across 140 alternating DPR-2 runs, DotGothic16 regresses 14.9% on WebGPU; the Noto CJK WebGPU signal crosses zero and its WebGL2 median reaches only −3.5%. The complete dual-backend guard therefore rejects the universal capped policy.

Six authenticated full-font fixtures cover sans, serif, script, Arabic, Devanagari, and Japanese stress. A seventh deterministic Noto Sans CJK JP subset covers only the authored Advanced Shaping Japanese corpus so the visual default uses a conventional sans rather than DotGothic16's intentional pixel style. Its source is 38,092 B; its Bitmap GLB is 65,996 B on one page; and its MTSDF artifact is 1,044,110 B gzip / 3,172,756 B raw / one page / 3,162,112 B exact padded base-level GPU memory. The full Noto CJK font remains the shaping oracle and Milestone 13 paging target. DotGothic16 remains an explicit full-face raster stress fixture, not the representative CJK visual default. A streaming test authenticates all fourteen artifacts, embedded source hashes, complete fixture-local glyph counts, page totals, and exact padded base-array allocations without rebaking them. The production build emits and links one exact font-notices artifact containing every redistributed license.

Bitmap, MTSDF, and Slug technique modules expose only persistent-scene construction, scene-update contracts, and their own raster metadata. The obsolete standalone preview constructors and their duplicate renderer, RAF, GPU-timer, telemetry, resize, and disposal lifecycles are removed; one source-boundary regression rejects their return.

Canonical font loading is owned exclusively by workloads/font-assets. Bitmap atlas, MTSDF configuration, and Slug allocation inspection live beside the corresponding persistent adapter under techniques; finite scenes, CPU references, readback normalization, and direct ABI work remain under benchmark/low-level and benchmark/targets. Generic renderer modules own only the persistent host, canvas/view state, activation, telemetry, timing, renderer configuration, and state restoration.

Each runnable example owns one workloads/<id>/ directory. Its definition.ts declares route metadata, controls, font policy, interaction, and Main/Presentation defaults; scene.ts is the framework-neutral public @pmndrs/text and Three.js example. Consumers import the exact file they need rather than routing through workload barrels, and the root catalog only preserves order and lookup. Shared structural contracts live under workloads/shared, while comparison-only contracts and registry wiring live under workloads/comparison.

The multi-technique retained implementation lives under surfaces/benchmark/scenes/comparison-workload and consumes those authored scene factories. It can use only an allowlisted set of generic host, canvas, telemetry, and activation primitives from renderer; it cannot create a renderer, animation loop, or GPU timer. Slug performance observations that require an isolated canvas enter through benchmark/probes/comparison-workload-preview, which owns one PersistentRenderHost, activates the same workload scene, and guarantees host disposal after release. The app and workload rail preserve the literal lazy scene chunk boundary. Keeping this 1,300-line host scene outside workloads leaves each workload directory as readable authored content and policy rather than mixing renderer borrowing, telemetry, font transactions, and route activation into the examples.

True product, conformance, and measurement targets remain under benchmark/targets. Reusable finite scenes, CPU references, and readback primitives remain under benchmark/low-level. The realtime raster comparison is a route-owned retained scene under surfaces/conformance/scenes, not a benchmark target.

app.tsx is a 37-line route entry with no controller or viewport implementation. routes/harness-route supplies the one shared component identity, controllers/harness-controller owns the route-independent state machine, and surfaces/harness owns renderer-aware layout and scene composition. surfaces/benchmark/benchmark-surface dispatches an authored workload to the selected technique, while comparison-workload-viewport owns the retained comparison activation, progress, errors, and causal probe attributes. Main and Presentation intentionally render the same HarnessRoute component type; separate Main and Presentation wrappers would remount the provider and violate canvas, renderer, and telemetry retention.

The deterministic TSL renderer baseline is an executable conformance target under benchmark/targets/conformance, not renderer infrastructure. The latest-value async queue is local to surfaces/benchmark, where the three React viewport controllers use it to serialize scene commits and collapse obsolete pending inputs.

Benchmark ipsum corpus

The corpus is an executable fixture, not display copy. Its five lines isolate ordinary Latin rhythm, numerals, kerning pairs, punctuation, standard ligature candidates, and compact mathematical notation. Inter must shape every scalar without glyph 0; the renderer rejects the corpus before upload if coverage regresses. Every selectable family receives the identical diagnostic and paragraph source text. The live surface reports source length and missing glyphs, so fixture coverage differences remain visible and comparable instead of being hidden by font-specific copy.

Lane Canonical text Primary signal
Latin Lorem ipsum dolor sit amet. Common word rhythm and spacing
Numerals Hamburgefontsiv 0123456789. Mixed round/stem forms and tabular sequence
Kerning AVATAR To Wa Yo — “quotes”. Strong kerning pairs and punctuation
Ligature candidates ff fi fl ffi ffl; (brackets). Repeated join candidates and spacing; this Inter frame does not itself assert substitution, which belongs to structured shaping conformance.
Mathematics x²+y²≈z²; 0≤α≤1; ±×÷∞√∑π→←. Superscripts, Greek, relations, operators, and arrows

Milestone 7.2 owns a product-facing advanced-shaping showcase over this same rendering path. It makes Arabic joining, Indic reordering, bidi, ligatures and marks, and CJK line breaking visible while paragraph-scale text streams into one stable measure. The showcase loads playing from its empty authored boundary. Play/Pause, Reset, and direct scrubbing provide deterministic transition points for Vitest, Vitexec, and visual evidence without sleeps or timer tolerances. Playback loops at the authored boundary; scrubbing pauses until the user explicitly resumes.

The showcase corpus is an immutable TypeScript discriminated union with exact integer timeline state. Each case now owns a focused conformance sequence and a longer live sequence. Grapheme segmentation keeps combining marks and complex-script clusters intact; seeking does not depend on JavaScript code-unit slicing. The live benchmark exposes edit, play/pause, reset, and scrub controls over the retained public Text object. Automatic playback reveals one grapheme on every application animation frame at a stable width, making continuous 60 Hz shaping and layout the default workload on a 60 Hz display rather than throttling updates to a slow typewriter cadence. Bitmap and MSDF center the paragraph measure in both viewport axes while keeping its text start-aligned, so the box has a stable horizontal origin and each line grows naturally before wrapping. Resident updates publish through ordinary Three.js matrix traversal; Text.ready is observed only to publish causal probe/telemetry completion and to report genuinely cold or failed preparation, not to make the renderer advance the text. The maintained GPU probe renders every authored case with zero missing glyphs, confirms the fixed anchor and measure, and requires multi-line wrapping; a separate exact conformance matrix deliberately retains its bounded source and historical hashes.

The CI-safe advanced-shaping target derives all 68 finite frames from that same corpus and sends each through the public Text object and bitmap batch construction at an explicit 800 CSS-pixel viewport and 16 px font size. Its exact Chromium 149 record covers five cases, 709 laid-out glyphs, 625 rendered instances, 72 draws, zero missing glyphs, 17,362 normalized layout bytes, and composite hash 51ba1d14; a wrong hash and a missing-glyph mutation are negative controls. The three recorded 8.5–11.3 ms durations describe this machine's end-to-end conformance execution only. They are neither live renderer costs nor portability thresholds. Hardware GPU pixels remain owned by the exact bitmap readback lane, while the admitted Vitexec product probe proves that each authenticated showcase fixture reaches the live WebGPU canvas.

The foundation closure gate executes 111 Vitest cases and 16 isolated headless Chromium targets from the current manifest, including forced-WebGL2 Bitmap/MTSDF/Slug, conformance, source-outline, React reconciliation, Worker fallback, paragraph contracts, advanced shaping, and rich spans. A package-owned live Paragraph Stress timing run retains 11,510 glyphs in one draw at 121 RAF FPS: frame p95 is 8.66 ms, renderer submission median/p95 is 0.405/0.905 ms, and the public text update-and-measure median/p95 is 5.725/7.405 ms. This attributes the remaining live CPU cost to text preparation rather than GPU submission; it is one local observation, not a portable budget guarantee.

The retained bidi/policy/UIKit and full CJK paragraph contracts again have executable generators. Both use the public Rust-plan Text API, keep each multi-width paragraph resident, and run in deterministic --check mode from the ordinary benchmark test and bake-fixture gate. The committed contracts remain byte-identical. Historical measurements produced before the f32 ABI retain their original numeric literal only when the regenerated public value is exactly f32-equivalent; the existing UIKit exact-width rounding seam is independently recomputed before its legacy literal is retained. Any material number, layout array, hash, identity, call contract, or document-shape change still fails generation.

The separate live performance observation runs the human WebGPU surface at explicit 1× DPR on Chromium 149 and an Apple metal-3 adapter. Each paragraph-scale script lane must settle its exact authored state with zero missing glyphs and then publish twelve causal FPS and GPU-report intervals; there are no sleeps or timing thresholds. The refreshed run observed 119.46–120.16 FPS, 0.2–0.3 ms median CPU submission, 0.3–0.5 ms CPU P95, 0.679–3.457 ms median GPU time, and 3.261–5.033 ms GPU P95 across 112–278 glyphs and one to fifteen draws. Initial public Text readiness was 7.2–22.0 ms and total startup 17.0–122.9 ms; the first cold Inter fetch dominates the high end. Text.ready includes shaping, paragraph layout, and bitmap-batch publication, so it is not mislabeled as a pure shape call; the dedicated HarfRust target owns that narrower metric. These machine observations are authenticated evidence, not cross-device budgets.

The package-size lane measures the item 8.1 MTSDF kernel separately from the coverage-capable item 8.6 baker and every initial browser or unrelated raster graph. The validated generator host is 11,543 raw, 8,466 minified, 2,658 gzip, and 2,364 Brotli bytes; the corrected optimized scalar kernel is 52,633 raw, 23,115 gzip, and 19,660 Brotli bytes. The complete MTSDF baker adds Fontations, bounded face-resolved coverage, and artifact packaging behind the optional subpath and measures 552,025 raw, 215,030 gzip, and 168,758 Brotli Wasm bytes plus a 26,940 raw / 19,117 minified / 5,530 gzip / 4,908 Brotli host. The Bitmap baker with the same coverage contract measures 626,940 raw, 234,735 gzip, and 180,503 Brotli Wasm bytes. The private TypeScript diagnostic entry is neither packed nor reachable from production graphs, and Rust profiling remains a non-default feature; the size lane rejects diagnostic code in shipped baker graphs and profiling/timing Wasm boundaries. The final Text lifecycle remediations move the browser-core graph from 329,665 / 251,133 / 73,068 / 56,025 to 330,343 raw / 251,524 minified / 73,143 gzip / 56,131 Brotli bytes without changing any baker host or Wasm artifact. A separate pre-coverage regression table bounds the accepted growth of browser core, both optional hosts and runtimes, and both baker Wasm modules in every measured representation. Complete reviewed ceilings apply on foreign hosts, while same-host regeneration must remain byte-exact. pnpm scripts run text:mtsdf-generator-profile additionally reports compile, initialization, cold-corpus, and warm-corpus observations only after all seven independent oracle hashes pass; it is generator evidence, not frame-rendering performance. Rejected SIMD variant reports remain historical decision evidence rather than maintained browser capture workflows.

Inter and Amiri retain their established roles. A pinned static Noto Sans Devanagari face adds the Indic lane without weakening the baker's explicit variable-font rejection. Advanced Shaping recommends a script-appropriate font for each case but exposes every baked fixture so a human can inspect coverage failures instead of having the selection silently locked. The CJK default is a reproducible HarfBuzz 13 subset of the authored Noto Sans CJK JP case; DotGothic16 remains available and explicitly labeled as pixel style. The subset is showcase evidence, not an answer to complete CJK distribution: the full 65,535-glyph Noto face remains the authoritative shaping/paragraph oracle and Milestone 13 owns chunked raster paging.

The Japanese showcase freshness check is reproducible on a declared build host but intentionally does not provision tools or download source. Its explicit prerequisite step authenticates and builds the pinned HarfBuzz 13.0.0 utilities through the source-archive hash and executable-version gate; the R3F example uses the same provisioner with its separately recorded 14.2.0 asset-tool identity. The provisioner includes hb-info beside hb-shape and hb-subset, so the shipped text glyphs command is tested against the same authenticated font-inspection tool used to discover font-provided names. The checks then require those ignored caches, rebuild their subsets in temporary storage, and compare the font, license, and manifest exactly. Upstream creates the utilities only when GLib development metadata is available, so provisioning requires -Dglib=enabled and fails during Meson configuration when that prerequisite is absent. CI installs libglib2.0-dev explicitly, reports the resolved glib-2.0 version, provisions both authenticated versions, and adds only the R3F asset version to later steps' PATH. Local macOS hosts that choose to provision must install both Homebrew glib and pkgconf so the equivalent metadata is discoverable through pkg-config. The provisioner disables unrelated optional HarfBuzz backends explicitly, keeping the source-build graph independent of other libraries installed on the host. GLib supplies the command-line frontend rather than the shaping, subset, or inspection implementation, and the exact HarfBuzz version plus generated bytes remain the fixture authorities.

The browser product also carries the React 19 subpath proofs. A shared registry target mounts public nested <Text> through a real React Three Fiber root backed by WebGPURenderer, retains one forwarded core object through width reflow and canonical restoration, matches pinned natural/narrow paragraph oracles, verifies two span paints in one draw, and submits a real renderer frame over three deterministic samples. Teardown explicitly disposes that retained paragraph before its target-owned font because R3F defers ordinary host disposal to idle priority; the later host disposal is idempotent. The live pending-resource probe intercepts the exact composed Inter request behind a manually released promise, observes the Suspense fallback before publication, releases the request without a timer, then proves the registered font key and all 2,937 glyphs before deterministic cleanup. The test renderer remains confined to package integration evidence and does not enter the product registry or application dependencies.

The initial deterministic browser probe is admitted with a checked-in record: 100 executions across 10 fresh GPU-friendly Chromium/Vite lifecycles, zero retries/failures, unique causal completion identities, and wrong-expectation plus withheld-completion negative controls. Probe exit status and every parsed lifecycle/environment field are validated before publication. Browser scripts navigate only through DOM readiness and then wait on the product's own completion promise or visible state; they do not use network-idle heuristics. Exact contract comparison rejects non-finite numbers, exotic objects, key-order differences, and missing or additional fields without JSON coercion. The current live probe executes the exact TSL graph on asserted WebGPU and forced WebGL2 backends before paragraph measurement, positioned-layout, bidi/policy, CJK, and mobile Playwright flows. This proves a real GPU shader workload while reserving the rendered-font claim for item 6.1.

Roadmap item 10.3 leaves browser core, every baker host, and every Wasm artifact byte-identical. Relative to the warm-publication baseline, bounded retained capacity adds 5,155 raw / 2,779 minified / 627 gzip / 598 Brotli bytes to the optional Bitmap closure, 6,038 / 3,148 / 778 / 762 to MTSDF, and 9,309 / 4,976 / 1,238 / 1,204 to Slug. A dedicated regression bounds those increments independently from the accumulated pre-coverage baseline. All three remain below the existing absolute 425,000 raw / 325,000 minified / 95,000 gzip / 75,000 Brotli renderer ceilings, so no absolute runtime, baker-host, or Wasm budget changes.

Package scripts

pnpm scripts run benchmark:presentation-screenshots retains one MTSDF screenshot for every verified workload on WebGPU and forced WebGL under the ignored benchmark cache.

Script Purpose
build Build runtime prerequisites once, measure sizes, build the Vite product, and validate font notices.
check Build prerequisites once, then run types, lint, format, tests, and the production build.
test Reuse one prepared build for size/fixture checks, Vitest, script discovery, headless conformance, and packaging.
dev Build the baker dependency and start the Vite application.

Run pnpm scripts list benchmark from the workspace root to discover current benchmark maintenance workflows.

The size lane is also a package-graph gate. Its consumer builds inspect emitted module membership rather than relying only on source text or byte totals: the browser-core entry must retain runtime baking as a dynamic chunk while excluding React, bitmap rendering, Node hosts, the Worker, the validator implementation, and portable-baker hosts from its initial graph. The lightweight shared version contract remains intentionally present. These assertions run for both readable and minified builds before size evidence is accepted.

The V0 autoresearch baseline is a fail-closed control artifact, not an active optimizer. Its generated evidence list authenticates the current package sizes, admitted harness, shaping, paragraph, bidi, CJK, and advanced-shaping conformance records at the exact root toolchain pins. A discriminated campaign state remains disabled; tests reject malformed evidence and prove that an enabled manifest cannot cross the campaign guard without a later explicit maintainer decision.

The packed-consumer lane builds and packs both workspace packages, extracts only their published tarballs into an isolated Vite application, and executes @pmndrs/text/runtime-bake through the installed module Worker in Chromium. Canonical Inter returns the exact 172,144-byte artifact and SHA-256 edf896923f38c9e6080e176540699a7b96b7cd15606b0522447750e7595170b5. This closes the gap between source-workspace Worker evidence and what an installed consumer actually resolves.

The text:kernel-lab-browser workflow runs the package-owned scalar, compiler-vectorized, and selected hybrid shaper artifacts in the project-pinned Chromium from a trustworthy loopback origin. It consumes the same captured 25,515- and 100,602-glyph typed arrays as the Node workflow and fails before timing unless every artifact reproduces the scalar horizontal, vertical, partial-tail, and unaligned hashes. The current Chromium 149 run executed the SIMD artifact, observed no warm memory growth, and supports the 64-cluster choice: at 100,602 glyphs its selected-hybrid p95 was 0.01875 ms versus 0.0625 ms scalar for chunk summaries, 0.009375 versus 0.053125 ms for break masks, and 0.0125 versus 0.04375 ms for bidi masks. The same run executes the production validated-policy interpreter over a representative 17-operation program and includes its F32×4, U32, and U16 buffers in the scalar/auto/SIMD byte-identity gate. At 25,515 glyphs, explicit SIMD measures 0.438 ms p95 versus 1.113 ms scalar; at 100,602 it measures 1.750 versus 4.350 ms. Browser timer quantization is visible in those figures, so Node retains the finer candidate ranking while Chromium supplies the independent engine-admission check.

The bake-host report separates the consumer phases without timing conformance work. Each offline sample creates a fresh Wasm baker and records initialization plus first bake as cold, then records a second bake on that instance as warm. Each isolated Chromium context queues two requests onto one Worker: first completion contains Worker/Wasm startup plus its bake, while the interval to second completion is the warm reused-instance bake. Three captured arm64/Chromium 149 samples preserve complete artifact parity; medians were 4.16 ms cold / 2.94 ms warm offline and 21.70 ms cold / 3.50 ms warm in the Worker. These are observations, not cross-host thresholds.

A released scene leaves the provider-owned canvas attached with its last complete frame while its replacement effect activates, avoiding a detach/reparent flash; provider teardown or removal of the owning anchor remains the detach boundary. The continuity probe requires the same connected canvas and exactly one renderer through explicit DPR 2→1→2 and Bitmap→MTSDF→Bitmap handoffs.

The benchmark plan owns target admission, correctness-before-timing, and product-E2E requirements.4

Footnotes

  1. The local hardware lane asserts the WebGPU backend through renderer initialization, renderer/canvas identity across aborted and successful finite jobs, and peak renderer concurrency of one while treating browser console, shader, and GPU validation errors as failures; the same lifecycle receives a separate forced-WebGL2 check.

  2. The retained Chromium 149 record authenticates all five generated files, exact source kinds and request counts, equal embedded/external work, and equal framebuffer identities on both renderer backends.

  3. The planning concept keeps rejected outline evidence separate from the current benchmark capability contract.

  4. Local GPU evidence supplements rather than replaces deterministic CI-safe checks.