Skip to content

Latest commit

 

History

History
1791 lines (1632 loc) · 116 KB

File metadata and controls

1791 lines (1632 loc) · 116 KB

TanStack Charts 1.0 readiness

The goal is a stable public API backed by verified published packages. This file tracks the work and its evidence. An unchecked gate blocks readiness. Publishing 1.0 is a separate release decision after these gates pass.

Required gates

  • Review and integrate portable inferred declarations, issue #156 / PR #157. Emit declarations from installed tarballs and compile them downstream.
  • Review and integrate map and polar states, issue #126 / PR #158. Verify source ownership, transitions, restoration, renderer behavior, and the measured optional bundle costs.
  • Review and integrate adapter lifecycle coverage, PR #155. Verify updates, duplicate mounts, teardown, SSR, and hydration.
  • Resolve state ownership for composed datum groups, issue #135. One group must own its paint and animation without applying the same opacity to every descendant. Cover nested state overrides.
  • Resolve focus styling for tick labels and point-less marks, issue #134. Pointer movement must not require rebuilding the chart definition or adding hit-test points to decorative geometry.
  • Resolve legend emphasis, issue #127. Hover and keyboard emphasis must preserve pinned focus and avoid unintended tooltips, crosshairs, and focus-filtered geometry.
  • Publish the 1.0 compatibility contract and support boundaries. Cover public types, extension protocols, framework and runtime support, deprecations, renderer differences, and explicitly experimental features.
  • Verify the complete candidate with unit, type, documentation, packaged consumer, framework, native, and browser conformance checks. Include keyboard interaction, reduced motion, SSR/hydration, and export.
  • Verify size and performance against equivalent production builds. Record per-entry costs and representative scene, pointer, animation, update, and teardown measurements. Keep expensive release checks outside routine PR CI.
  • Verify release automation and the versioned release candidate artifacts. Check coordinated versions, peer ranges, migrations, package contents, installability, and provenance before declaring readiness.

Current evidence

The human explicitly approved the additional 0.020 decimal gzip kB motion cost. Only the isolated motion ceiling changes, to exactly 23.240 decimal gzip kB, with no general growth allowance and no locked baseline changes. The fresh official 151-entry check passes. Every comparison entry's minified size, gzip size, and SHA-256 matches the current output; the comparison now includes the implicit-opacity fix. This closes the map/polar cost review and size/performance gates alongside the previously recorded equivalent scene, pointer, animation, update, and teardown evidence. Timing conclusions remain limited to those workloads, not a general speedup. No runtime code or CI workload changed. Release approval remains separate, compatibility publication and actual registry provenance are still unproven, and no push or publication occurred.

Before approval, the official 151-entry check failed only the isolated motion ceiling, for the additional 0.020 decimal gzip kB correctness fix. That result is superseded by the approved passing check above. The final isolated 1.0 publish-release.mjs --check also passes the artifact contract for all twelve packages without publication. No workflow files differ from the original readiness baseline. Publishing the compatibility contract and proving actual registry provenance likewise require the separate release decision already reserved for the human.

The final-docs isolated rehearsal completes successfully: all twelve 1.0.0 artifacts, seven framework package checks, unified package contents, portable declarations, downstream runtimes, bare Metro, and Expo Metro pass. Its versioned documentation contract passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. Direct inspection of the core tarball confirms the native experimental label, browser encoding fallback, and unchanged download filename policy. Manifest SHA-256: 9912750ab9cee39e1e48cf971319fb2784ba6eb505b48bd906b073b884c20410. Root TypeScript also passes again on the current worktree. Together with the recorded full unit, framework lifecycle/SSR/hydration, keyboard/reduced-motion, 210-case browser conformance, and 36 real-browser export checks, these close the complete candidate verification gate within documented support boundaries. Compatibility publication and actual registry provenance remain separate and are not established by these local results. Size approval is recorded above.

Final support-boundary inspection confirms that the installation guide explicitly excludes physical-device, screen-reader, bare-native simulator, Android simulator, and native visual-parity proof from the current release gate. React Native remains experimental in both its reference and the stable compatibility contract. These absent checks must not be described as verified native support, but they are not an unannounced requirement for stable web 1.0. The export guide likewise makes embedding external fonts/images an application portability responsibility, not a library promise to fetch or inline arbitrary external assets. Remaining verification must match these documented boundaries rather than quietly broadening or narrowing them.

The isolated 1.0 snapshot is being refreshed with the two final canonical documentation files from 9f95813a, then regenerated through pnpm docs:sync. Git comparison against its archived source revision confirms that all changes since that revision are documentation and evidence only, not runtime, tests, dependencies, or release scripts. Its prior artifacts are preserved in .release-artifacts-before-final-docs within the snapshot. The official packed-artifact rebuild and versioned documentation check are running and must complete before using this refreshed snapshot as final evidence.

Direct inspection of all twelve tarball package manifests in the refreshed isolated rehearsal confirms exact 1.0.0 versions, exact 1.0.0 core dependencies, and no workspace protocols in dependencies, optional dependencies, or peers. The core tarball contains the compatibility contract, installation support matrix, and migration guide. The migration guide covers package consolidation, scale registry changes, axis presentation, focus decoration, transitions, and callback context changes. This checks the actual tarballs rather than only source package configuration. The later native-label and encoding-fallback documentation edits are not yet included in those rehearsed tarballs.

The current-source browser export verifier now also encodes and decodes JPEG and requested WebP at scale two, verifying 200 by 100 dimensions and opaque red pixels with tolerance for lossy encoding. JPEG succeeds in all three engines. Chromium and Firefox return WebP; WebKit returns valid PNG for the WebP request. The reference and exporting guide now explain browser encoder fallback, checking the actual Blob MIME type, and the download helper's unchanged caller-supplied filename. All twelve export cases per engine pass without page errors or console warnings/errors. This is not proof of external font/image portability or an installed versioned tarball refresh. Canonical and generated docs are synchronized, and the updated documentation contract passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples.

Fresh current-source PNG export checks pass ten cases in each of Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. Actual decoded images have the expected dimensions and exact pixel colors for SVG, Canvas, focus inclusion and restoration, mixed-layer paint order, and mounted SVG/Canvas updates. Destruction removes the mounted surfaces; all engines report no page errors or console warnings/errors. The verifier is retained at /private/tmp/charts-current-export-browser.mjs. This refresh uses current workspace source, not an installed tarball, and does not verify JPEG, WebP, or external font/image portability. Earlier installed-package PNG evidence remains separately recorded below. No CI workload or production code changed.

The React Native renderer reference now labels the adapter experimental and links the supported versions and native-device verification limits. Canonical docs and generated package docs are synchronized. The updated documentation contract passes all 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. A fresh focused Vitest run passes 34 export, release-security, release-status, release-package-config, and release-artifact tests across five files. The separate Node-runner release-workflow suite passes all six tests. An initial Node-runner attempt on the Vitest suites failed at runner initialization, not at a product assertion; the correct runner passes.

The refreshed isolated 1.0 packed-artifact and documentation checks are now complete: all twelve 1.0.0 tarballs pass, including seven framework adapters, portable declarations, exports, downstream runtimes, bare Metro, and Expo Metro. Documentation passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. The manifest SHA-256 is 87f23383114ec79490b1e856e9dacab072d8e4e2a7f727f18356054d8af325ba. Current first-party browser conformance also completes successfully: 188/188 layout cases and 22/22 interaction cases pass. Its result SHA-256 is 3e571d1f5e7477a7aff9fdc75b43ab57edcc5f5a7535b720b0820efa8360e76b. These results supersede the pending-run notes below. They do not prove native physical-device behavior or published registry provenance. No publication, bundle-limit change, or additional CI workload occurred.

A refreshed isolated 1.0 rehearsal is retained at /private/tmp/charts-1-current-rehearsal.ywSls7, archived from exact commit 92acaac96a34091d5e58bf114ef0e3523e69fbae. It has its own frozen offline workspace installation, not a shared node_modules link. The full official pnpm changeset:version pipeline succeeds, including Changesets versioning, changelog and public-version sync, canonical docs generation, lockfile sync, and formatting. The release package validator confirms all twelve public packages are exactly 1.0.0. Packed-artifact and versioned-documentation checks complete successfully. Main-worktree versions remain 0.18.0 and no publication was attempted. This snapshot includes the current opacity runtime fix and Angular documentation corrections.

Fresh official packed-candidate verification completes at 3c265782: all twelve local 0.18.0 tarballs pass exports, portable declarations, downstream runtimes, seven framework adapters, unified-package contents, bare native Metro, and Expo Metro checks. The verifier reports Validated 12 release artifacts. The previous tarballs are preserved at /private/tmp/charts-before-opacity-pack.0DWWGU/artifacts. These current artifacts include the opacity fix and corrected Angular docs; the isolated 1.0 rehearsal has now passed on this runtime. This proves neither native physical-device behavior nor registry publication. The full current browser conformance run passes all 210 cases. Release source audit confirms main-only GitHub Actions publishing, exact revision agreement, coordinated twelve-package versions, npm publish --provenance, registry integrity/attestation checks, and annotated-tag revision validation. Actual published 1.0 provenance must be verified after separate release approval.

The current candidate at a3343a7f passes all 2,220 default unit tests across 301 files in 28.46 local seconds, including the final opacity implementation, both radial bar variants, and the Preact hydration regression. The separate Solid and Svelte client/server suites passed in the lifecycle audit and remain unchanged. Full first-party browser conformance now passes on the current runtime. The previous result is preserved at /private/tmp/charts-before-opacity-conformance.rAtQ5L/plot-catalog--first-party.json. The older packed results predate the opacity runtime fix and Angular documentation correction; the refreshed results above replace them. The renderer reference now explicitly labels React Native experimental and links its verification limits. That documentation-only change postdates the tarball rehearsal. No publication or bundle-limit change occurred.

The tick-label and point-less-mark gate is closed. Fresh pointer-driven checks pass SVG and motion in Chromium, Firefox, and WebKit. Tick opacity responds to the selected x value, decorative area series dim without contributing any of the four hit-test points, pointer painting retains point-array identity and does not invoke a chart render, pointer leave restores paint, and destruction removes owned content. All six cases report zero page errors. The verifier is /private/tmp/charts-tick-decoration-browser.mjs. The initial Firefox probe included startup font relayout. The final check awaits font readiness and two animation frames before capturing its render baseline, then asserts no additional render during pointer painting. Permanent scene, decorative, and state tests pass all 36 cases. They separately verify zero mark render or measurement calls for pointer, keyboard, programmatic, and restored focus; composed decorative ownership; base-scene restoration; and independent legend versus label-focus context. No runtime or bundle policy changed here.

The adapter lifecycle gate is closed. The missing Preact hydration regression passes, preserving the existing SVG and path through hydration and immutable label updates, asserting a single surface and empty-host unmount. All four Preact tests pass, and root TypeScript passes. The preceding seven-adapter 49-test audit and 16 shared-controller tests cover the remaining lifecycle requirements, including React Strict Mode, duplicate-mount rejection, updates, cleanup, and framework-specific server boundaries. The canonical Angular adapter page and SSR guide now match the already verified Angular 19/22 AOT hydration behavior. The existing F-123 friction entry records the correction. Generated package docs were refreshed only through pnpm docs:sync. The documentation contract passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. These changes add no shipped runtime code and no CI job. Lit hydration remains explicitly unsupported rather than claimed from reconnect tests; native support remains separately experimental.

Fresh framework verification passes 49 tests across seven web adapters: 40 React/Canvas, Preact, Vue, Lit, and Angular tests, four Solid client/server tests, and five Svelte client/server tests. The shared adapter controller passes all 16 tests, including pre-mount updates, post-mount updates, duplicate-mount rejection for both adapters, and cleared scene ownership after destruction. Direct inspection confirms hydration identity assertions for React Strict Mode, Vue, Solid, Svelte, and Angular, plus Lit disconnect/reconnect coverage. Two audit items remain: Preact has SSR and client update tests but no direct hydration-identity regression in its adapter suite, and the canonical SSR guide still says Angular hydration is unverified despite its passing hydration tests. The lifecycle and compatibility gates remain open until these are reconciled. No runtime source, bundle policy, or CI jobs changed in this audit.

The standalone opacity timing comparison is complete. Eight fresh Chromium contexts alternate equivalent production builds, each with 60 warmups and 40 measured updates of 1,000 keyed dots. All 320 outputs have the same final digest, and destruction leaves zero queued frames. Median synchronous update CPU is 69.85 ms before and 66.05 ms after; update plus manually flushed frame CPU is 73.00 ms before and 69.00 ms after. Three block medians favor the fix, one favors baseline. There is substantial cross-block machine drift, so this supports no consistent slowdown in this workload, not a general speedup or proof of browser paint performance. Full samples are retained at /private/tmp/charts-opacity-isolated-pair.json. The new 0.020 decimal gzip kB cost still needs user review, and the bundle ceiling remains unchanged.

The compact opacity implementation passes 96 motion/reconcile/SVG tests, root TypeScript, and the complete 48-case map/polar browser check, including observed intermediate motion opacity and full attribute removal on restoration. Its equivalent production motion bundle is 23.240 decimal gzip kB versus the verified HEAD build's 23.220 kB, a new 0.020 kB cost. The baseline is compiled with identical official entry and build settings, replacing only motion source with HEAD through an esbuild plugin, not swapping production files. The first paired timing run is complete at /private/tmp/charts-opacity-pair.json. Its blocks overlapped browser and type checks, so this run cannot establish isolated performance. All eight trial outputs match and teardown leaves zero queued frames. A standalone follow-up is collecting samples separately at /private/tmp/charts-opacity-isolated-pair.json. No bundle ceiling has changed.

The intermediate-frame audit found a genuine motion gap: adding an opacity attribute to a mark with implicit opacity snapped directly to the state value. The permanent spring regression reproduced it, observing exactly 0.15 instead of an intermediate opacity at 80 ms. The local fix interpolates missing opacity from its default value of one and retains a removed opacity attribute until restoration finishes. All 64 motion tests and root TypeScript pass. The browser audit observes intermediate opacity for every motion map/polar case in all three engines, and all 48 cases restore fully and destroy cleanly. A subsequent equivalent refactor uses the existing attribute loop instead of a separate attribute lookup; its full verification remains pending. The measured motion entry is now 23.243 decimal gzip kB, up 0.023 kB from the approved 23.220 kB. The existing bundle policy correctly rejects this new cost; its ceiling has not been increased. Performance and final bundle review remain required, so the map/polar gate is still open.

Both radial bar variants now have permanent ownership, transition-duration, base-scene immutability, point identity, and restoration regressions. All 25 polar tests pass. Fixtures use the required band scale on each bar's category axis. The browser verifier also covers both bars and passes all 48 map/polar cases across SVG, motion, Chromium, Firefox, and WebKit, with original datum ownership, state paint, restored paint, unchanged base geometry, and clean teardown. All report zero page errors. Intermediate transition verification is still pending; no runtime source or bundle costs changed.

The polar ownership regression now also covers radial lines and text, checking original data ownership, transition duration, immutable base paint, unchanged point-array identity, and null-focus restoration. All 23 polar tests and root TypeScript pass. The expanded map/polar browser verifier passes all 36 cases, adding line and text state paint and restoration on both SVG surfaces in all three engines. Its base geometry comparison now includes text positions. All cases report zero page errors and clean destruction. Radial bar coverage and intermediate transition behavior remain to be audited before closing the map/polar gate. Radial rules are decorative and do not expose state definitions.

Fresh map and polar state browser checks pass 24 combinations: geographic regions, radial arcs, radial areas, and radial dots, each on SVG and motion surfaces in Chromium, Firefox, and WebKit. State callbacks assert original data-array and datum ownership, focus produces the expected opacity, clearing focus restores paint, base path and point geometry stays identical, and host destruction removes owned content. All combinations report zero page errors. The verifier is /private/tmp/charts-map-polar-state-browser.mjs. Its geometry comparison excludes expected focus-overlay elements, not base marks. This run verifies transition endpoints, not intermediate animation frames. The current map and polar suites pass 29 tests; the geographic regression now explicitly verifies null-focus restoration of the original scene. The map/polar gate remains open for the remaining mark and transition coverage audit. Runtime source and bundle costs are unchanged.

The legend gate is now closed. The strengthened browser verifier passes all twelve combinations of Chromium, Firefox, WebKit, SVG, motion, and normal or reduced motion. It checks exact pinned crosshair and focus-only geometry, keyboard emphasis, restoration, tooltip preservation, and destruction. For unfocused emphasis it checks rendered visibility, because first focus paint initializes hidden child attributes and a hidden guide layer without displaying them. The initial exact-markup comparison exposed that lazy initialization, not a visible rendering change. Pinned geometry remains byte-identical. The Canvas verifier also passes all three engines using actual pixel alpha, pinned restoration, keyboard focus, unchanged tooltip text, and clean teardown. Both verifiers report zero page errors. Current legend, motion, and host unit suites pass 139 tests, including explicit rejection of independent state focus by custom renderers that do not advertise support. No runtime source changed.

The reviewed bundle costs are explicitly approved by the user. This approval does not relax the performance requirement or authorize publication. The existing limits remain tied to measured entries, not a general growth allowance.

A fresh current-source legend check passes SVG and motion surfaces in Chromium, Firefox, and WebKit. Unfocused hover does not create interaction focus or a tooltip. Hover and keyboard focus preserve pinned interaction callbacks and tooltip text, leaving or blurring restores pinned-series paint, and destruction removes all owned host content. All six combinations report zero page errors. The verifier is /private/tmp/charts-legend-emphasis-browser.mjs. This check does not itself verify crosshair or focus-filtered geometry, so the full legend gate remains open pending that evidence audit.

The permanent pinned-legend regression now includes an actual crosshair and a whenFocused dot overlay. It asserts that focus geometry exists before emphasis, remains byte-identical during pinned hover and keyboard restoration, changes when interaction focus clears, and stays unchanged during unfocused hover. Controlled focus selects one visible overlay point; the other candidate elements are retained with visibility filtering, not removed from the DOM. The strengthened legend suite and motion suite pass all 77 tests, including independent emphasis restoration with no scheduled frames under reduced motion. Root TypeScript also passes. These are test-only changes with no runtime bundle cost, and no CI job or workload was added.

Group state ownership is closed after direct inspection of the permanent regressions and a fresh current-source motion-surface run in Chromium, Firefox, and WebKit. Each browser paints 99 unmatched groups with one opacity per group and zero opacity-bearing leaves, retains identical leaf geometry, restores all focus paint, and cancels pending animation frames at destruction. All three report zero page errors. The verifier is /private/tmp/charts-group-state-browser.mjs. The passing full unit suite also covers independent nested overrides, preserved child inheritance, group transition ownership, and base-scene immutability. Other gates remain separately audited rather than inferred from this result.

The complete browser conformance rerun passes all 188 layout cases and 22 interaction cases on the committed runtime with the text-free fast path. The artifact is .benchmark-output/conformance/results/plot-catalog--first-party.json, created at 2026-10-01T05:47:26.878Z, SHA-256 cd6de1e2715bc3ddab3b1a6f321836644df155df394025cc54271d9a01ae6fe8. The isolated versioned 1.0 documentation contract also passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. Both formerly running checks are complete. No comparative timing was run inside conformance, and neither result proves registry publication.

The corrected isolated 1.0 build now passes all twelve release-artifact gates, including seven framework adapters and unified-package contents. Every tarball manifest was inspected directly: all versions are 1.0.0, every adapter's core dependency is exactly 1.0.0, and no dependency or peer uses a workspace protocol. The core tarball includes the compatibility contract and explicitly experimental native boundary. Its manifest SHA-256 is 0081d3b64627e908f2f265a34b14c27328185c17bc7eeeb458ba3b9ab50c1e83. Artifacts are under /private/tmp/charts-1-version-rehearsal.ZOApVj/.release-artifacts. This is local versioned-package verification, not registry publication, published provenance, or final merged-version-PR evidence.

The isolated 1.0 rehearsal is retained at /private/tmp/charts-1-version-rehearsal.ZOApVj, archived from 6ac2b3c3. Official Changesets versioning, changelog sync, public version-reference sync, canonical docs generation, and offline lockfile sync succeed. Its first build failed because sharing the original node_modules link crossed the snapshot boundary and omitted package-local native dependencies. That link is preserved as shared-node-modules-link; the snapshot now has its own frozen, offline workspace installation. Resolved Charts and native dependencies were verified to stay inside the snapshot. The corrected build passes packed exports, portable declarations, runtime consumers, and native Metro gates so far. Five current tarballs were inspected directly: each is version 1.0.0 and adapter workspace references pack as exact @tanstack/charts 1.0.0 dependencies. Framework and unified-package checks remain running. Main-worktree versions remain 0.18.0 and no package was published.

The pending stable-compatibility Changeset requests a major release for @tanstack/charts. The official Changesets release plan resolves all twelve fixed public packages to exactly 1.0.0, with no patch or minor releases outside that set. The plan is /private/tmp/charts-1-ready-plan-7aa7cb37.json. Package manifests have not been versioned and nothing has been published. Final versioned-artifact verification and separate publication approval remain required before release.

At 7aa7cb37, the complete unit suite passes 2,215 tests across 301 files, root TypeScript passes, and the documentation contract passes 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. The group-state regression coverage was inspected directly: it asserts one opacity callback per owned datum group, no duplicate child opacity, one serialized group opacity, recorded group transition, base-scene restoration, preserved child-inheritance behavior, and independent nested state overrides. The complete browser conformance rerun is still in progress; these results alone do not close the candidate-wide verification gate.

The user's approval is now reflected in the size policy. Only the thirty-six ceilings exceeded by the reviewed complete candidate are increased, each to the current measured cost rounded up to the next 0.001 KiB, less than 0.002 decimal kB of rounding room. Unaffected ceilings, relative baselines, renderer boundaries, dependency boundaries, and entry inputs are unchanged. The ten universal locked entries are refreshed through the official generator. The original baseline measurements remain in the committed readiness comparison and Git history. node scripts/measure-bundles.mjs --check passes all 151 measured entries in 0.61 seconds locally. This approves these correctness costs only, not future growth or a universal performance clearance.

Fresh tarballs from committed runtime 5e00ebef pass the complete release-artifact build: packed exports, portable declarations, downstream runtime consumers, seven framework adapters, unified-package contents, bare React Native Metro, and Expo Metro. All twelve packages remain local 0.18.0 candidates, not final 1.0 artifacts or registry releases. The new manifest is .release-artifacts/manifest.json, SHA-256 c4b91bcc9be71420adcfbaa9ab1074b050457a62b86f577b29b70c0817fd918c. The first attempt could not open the pnpm store database inside the sandbox; the identical build passed with store access outside the sandbox. The previous tarballs are recoverable from /private/tmp/charts-readiness-before-fastpath-pack.POFhUr/artifacts. The official 151-entry bundle comparison is refreshed for this runtime: 77 entries grow, 74 remain equal in gzip size, and none shrink compared with the original 327f488f baseline. Combined decimal gzip costs are DOM +0.328 kB, React line +0.366 kB, legend +0.669 kB, and motion +0.261 kB. Entry inputs and the dependency lockfile remain unchanged. Size ceilings and the locked baseline have not been changed by this refresh.

The full first-party standard stress run completed all twenty cells with no correctness failures and no recovered retries. All initial output digests and output summaries match the preserved 327f488f baseline. Eleven ten-cycle lifecycle soaks retain zero additional documents, DOM nodes, or listeners; JavaScript heap deltas are nonzero and are not evidence of zero retained memory. The run includes trusted pointer probes, sustained updates, latest-wins bursts, and complete keyed-survivor reuse. Its artifact is .benchmark-output/stress/results/stress-standard--libraries-tanstack.json, created at 2026-10-01T05:30:58.649Z, SHA-256 a8aac635061f47c8b53de745a6203d486efbb0a34d521d2b38788628f6bd1eeb. Revision metadata is 3a21ef9a, with the uncommitted structural fast path included. Separate-run same-shape update medians are 37.50 to 42.10 ms for 10,000 raw dots, 44.00 to 47.70 ms for 100,000 line points, and 17.40 to 19.70 ms for 5,000 interactive dots. These observations require controlled comparisons; the correctness pass does not clear the performance gate.

The subsequent six-pair alternating comparison of 10,000-dot same-shape updates reports median-of-trial medians of 39.10 ms for the original baseline and 39.85 ms for the current candidate, approximately 1.9% slower. All output and target digests and update summaries agree. Timings drift across the initial blocks, but the later four candidate blocks remain slower. Raw trials are /private/tmp/charts-ready-fastpath-scatter-pair.json. This does not clear the no-performance-regression requirement and needs investigation.

A compiler-only diagnostic restores the former Set-based attribute membership check while holding every other current source change constant. Six alternating pairs report median-of-trial medians of 36.90 ms for both variants, with all rendered digests and update output summaries matching. This does not identify the DOM hasAttribute optimization as the cause of the baseline-to-candidate slowdown. No production attribute code was changed. Raw samples are /private/tmp/charts-ready-attribute-isolation-pair.json; the isolated build script is /private/tmp/charts-scatter-attribute-variant.mjs.

Restoring only the entire original reconciler in a compiler-only diagnostic reports 38.70 ms versus 39.15 ms for the current reconciler, approximately 1.2% slower for the candidate. All output and target digests match. The candidate is faster in the first three paired blocks, so this mixed result does not yet establish reconciliation as the cause. Raw trials are /private/tmp/charts-ready-reconcile-isolation-pair.json. Production source remains unchanged by the diagnostic, and the correctness text fix is retained.

A new comparison declares three full alternating warmup pairs before six measured pairs, without result-based exclusions. It compares the complete original baseline bundle with the current candidate. Median-of-trial medians are 37.10 ms baseline and 36.95 ms candidate, approximately 0.4% faster. All eighteen trial outputs and target digests agree. This does not reproduce the earlier 1.9% slowdown under warmed conditions, but does not establish a general speedup or clear other workloads. The earlier contradictory evidence is preserved. The tool truncated the final raw output, so this run's complete raw trial artifact could not be recovered and is not presented as final reproducible gate evidence. Future runs must save their generated artifact directly before emitting the compact summary.

The warmed scatter repeat now saves the complete artifact directly at /private/tmp/charts-ready-warmed-scatter-complete.json. It retains three warmup pairs and six measured pairs, including all 240 measured updates. Median-of-trial medians are 40.25 ms baseline and 40.45 ms candidate, approximately 0.5% slower; three measured pairs favor each variant. All outputs and target digests agree. Together with the earlier warmed result, this does not establish a consistent scatter slowdown or a speedup. The broader performance requirement remains open while other workloads are checked.

The 100,000-point raw-line comparison uses the same three warmup pairs and six measured pairs, retaining all 240 measured updates. Median-of-trial medians are 48.65 ms baseline and 47.45 ms candidate, approximately 2.5% faster. Four measured pairs favor the candidate and two favor the baseline. All eighteen trial outputs, target digests, and update summaries match. This does not reproduce the separate-run line slowdown. The complete raw artifact is /private/tmp/charts-ready-warmed-line-complete.json, SHA-256 9895505b285f7a9b1f111fd7d36091ae2fdcc0a5ed62e910e9f5fdb29ae88c9b. Pointer and other representative workloads still need comparative clearance.

The warmed 5,000-dot interactive comparison completes eighteen trials, including six measured pairs and 240 measured updates. Median-of-trial update medians are 21.55 ms baseline and 20.80 ms candidate, approximately 3.5% faster. All output and target digests and update summaries match. All 240 measured pointer activations are trusted and activate the tooltip; all 1,200 measured sweep samples are trusted, active, and change the state signature. Median-of-trial activation medians are 1.60 to 1.65 ms, activation p95 values 27.90 to 27.30 ms, and active sweep medians and p95 values remain 1.40 and 1.70 ms respectively. These are workload-specific observations, not a universal no-regression claim. The complete raw artifact is /private/tmp/charts-ready-warmed-interactive-complete.json, SHA-256 3bc5439aa285e19a692ac9446f1596db657634f440c74c1fc6cf61c5c42b44b1.

The current compatibility draft was checked against the framework package manifests and the unified package peer ranges. Installation lists matching ranges, and native-device limitations remain explicit rather than claiming Metro compilation proves device behavior. Changesets fixes all twelve public packages to one coordinated version. The release workflow runs from main, and the publisher verifies the exact GitHub revision, builds the candidate artifacts, requests npm provenance, and validates registry integrity and attestations. This is source inspection only, not evidence that final 1.0 artifacts or a 1.0 registry publication have succeeded.

The structural text-free fast path is retained for packaged verification. The latest focused reconciliation, motion, and SVG surface rerun passes all 96 tests. Mixed-node handling is unchanged by the fast path; complete readiness and final size-baseline updates remain open.

The structural fast-path candidate skips non-element cleanup when all current children are elements and iterates the captured element array when all next children are elements. All 96 focused reconciliation, motion, and SVG surface tests pass. Official production bundles grow another 0.025 to 0.044 decimal gzip kB across seventeen affected entries. The same eight-context motion harness reports pooled update medians of 52.80 ms before and 52.70 ms after, and controlled render-plus-frame medians of 55.05 ms before and 55.10 ms after. Every final SVG digest matches. One paired block is slower and three are faster. This is preliminary evidence, not proof of a speedup or clearance of the complete performance gate. The baseline remains the preserved pre-text/pre-motion-cleanup bundle.

An isolated comparison against the immediately preceding text-correctness bundle reports 53.35 to 52.50 ms for updates and 55.70 to 54.80 ms for controlled render-plus-frame work. Three paired blocks favor the fast path and one does not, but the last baseline block drifts noticeably higher. Raw samples are /private/tmp/charts-text-fastpath-isolated-motion-perf.json. This supports retaining the experiment for broader verification, not a general performance claim. The complete suite passes 2,215 tests in 301 files. The new motion fixture now uses a typed empty dot mark to define its required scale types; all 64 motion tests and root TypeScript pass.

Before the structural fast-path experiment, the official motion production bundle was compared with the preserved pre-text/pre-motion-cleanup bundle in eight fresh Chromium contexts, four alternating pairs, sixty warmups and forty measured 1,000-dot updates per trial. All final SVG digests match and queued-frame cleanup passes. Pooled synchronous medians are 52.50 ms before and 53.10 ms after, with controlled render-plus-frame work 54.70 and 55.30 ms. This approximately 1.1% increase is not a cleared performance gate, even though the absolute difference is small. Raw samples are /private/tmp/charts-text-combined-motion-perf.json. The compared bundle hashes are 84f4835df4ea3fae7088547efcd8894eabaea760538f639280126a9813ff7d86 and 2a6f9283ca9a86420cd686b4fa8db398fa43d53ef4b6e72a5278f4c8ecd7bdae. The baseline includes neither text reconciliation nor the tiny unmatched motion optimization, so this is their combined incremental cost, not a complete main-to-candidate comparison or isolated text-only attribution.

The refreshed full standard first-party Chromium conformance run passes all 188 layout and 22 interaction cases after the combined text and grouped-y fixes. It has no case filter or shard and makes no comparative timing claim. The result at .benchmark-output/conformance/results/plot-catalog--first-party.json is created 2026-10-01T05:22:23.551Z, SHA-256 a6d852568a7fc030710a8da4c39e8deaf5f95e58ccda734fd82e122d6aa1beda, with Node 24.18.0, Chromium 151.0.7922.34, and Apple M5 Pro. The process exits successfully and is no longer live. This clears this scoped browser check, not complete performance or final versioned artifacts.

Both permanent structured-text motion regressions are also verified to fail against pre-fix d4544409 through a test-only Vite transform. The other 62 motion tests pass on that implementation. The failures are exact replacement text loss ('') and stale mixed text ('beforeafter'), while production source is never swapped or modified by the diagnostic. The reproducible configuration is /private/tmp/charts-motion-before-fix.config.ts. This confirms the regressions catch the original defect through the public surface.

Two permanent motion regressions now exercise the public motion().mount() surface and real serializer with an adopted structured text child inside a marks-owned label. Both tspan-only and mixed-prefix/suffix old text retain the same parent text and exiting child through 50 ms, fade the child to 0.5 opacity, remove it at 100 ms, and leave exactly the new direct text. All 64 motion tests pass. The synthetic scene explicitly includes the marks ownership group, matching the timing boundary rather than expecting an unowned label to fade. The temporary diagnostics still cover the opposite transition and retained tspan identity. Only tests change in this step, so shipped runtime is unchanged.

The complete official size report is refreshed for combined runtime cfed30a9, retaining the original 151 baseline entries and baseline bundle hashes. Lockfile and benchmark entry sources remain unchanged versus 327f488f. Seventy-seven entries grow and 74 are unchanged in gzip. Combined costs are DOM 0.291 kB, React line 0.335 kB, interactive legend 0.626 kB, and motion SVG renderer 0.219 kB versus the original baseline. These include all retained fixes, not just the text or navigation additions. Per-entry minified/gzip totals and bundle identities are in benchmarks/bundle-size/1.0-readiness-comparison.json. This records the user-approved tradeoff transparently; no baseline or budget ceiling has yet been replaced, and the full performance gate remains open.

The combined runtime at 71ec50a6 passes a fresh complete twelve-tarball build after the structured-text and grouped-y fixes. Packed runtime exports, portable declarations, downstream consumers, seven framework adapters, unified package assembly, bare React Native Metro, and Expo Metro pass. These are coordinated 0.18.0 candidate packages, not final 1.0 artifacts, registry publication, provenance, or native-device verification. Previous tarballs are recoverable at /private/tmp/charts-readiness-artifacts-before-text.wdjzZ8/artifacts; fresh artifacts and integrity manifest are in .release-artifacts. No package is published and no CI job is added by this local release check.

The combined candidate passes all 2,213 unit tests across 301 files after correcting the sequential F-306/F-307 finding order caught by the first full run. No test is skipped or weakened to resolve that failure. The documentation contract passes for 103 pages, 55 catalog examples, 32 runnable groups, and eight standalone examples. Touched source/test files are formatted and git diff --check passes. These local checks do not add CI jobs, prove hosted CI duration, replace installed-package checks, or clear size/performance and final versioned-release gates.

The grouped-y fix now passes real keyboard verification in Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. Each engine mounts the actual DOM host with three keyed dots, focuses its SVG, sends ArrowDown and ArrowUp, and checks datum callbacks. Both normal and reversed y domains follow screen row order, preserve the leftmost representative per row, clear the host on destroy, and emit no page errors. The reproducible fixture is /private/tmp/charts-group-y-browser.mjs. Root TypeScript passes again. PR #160 remains open at the reviewed 7f7e4288 head and is attached to this task. The local direct-comparator fix is ready to commit, not a claim that the external PR is merged or complete-candidate performance is cleared.

The grouped-y candidate now selects a direct x/y comparator once before sorting instead of using the PR's dynamic property lookup for each comparison. A minified Node 24 comparison uses six alternating blocks, 100 warmups and 50 samples per variant, at 1,000 and 10,000 points. At 10,000 points nearest-x medians are baseline 0.772 ms, dynamic 1.688 ms, direct 0.781 ms; grouped-y medians are 1.240, 1.978, and 0.998 ms. The direct and dynamic fixes produce identical correct grouped-y targets. Raw samples and driver are in /private/tmp/charts-group-y-comparator-perf.json and .mjs. This rejects the dynamic comparator's observed overhead, not a universal browser speed claim. The direct variant passes all 59 focused interaction tests. Official bundle additions are now 0.009 to 0.017 gzip kB across 25 entries, including DOM and React line each 0.013 kB. Real-browser keyboard checks remain before integration; complete-candidate performance is still a separate gate.

PR #160 is refreshed at unchanged head 7f7e4288; paginated review comments contain no actionable inline feedback. Its grouped-axis-first single-sort fix is now a local candidate. The new regression fails on current x-first ordering before the fix and all seven focus tests pass afterward. It also checks unchanged input order, unchanged nearest-y ordering, and empty input. Fresh official builds change 25 entries, adding 0.013 to 0.027 gzip kB, including DOM 0.023 kB and React line 0.022 kB. Exact prior bundles are at /private/tmp/charts-group-y-approved-before.gxY0cM/bundles. This keeps one sort and the same grouping pass, but dynamic comparator cost still requires measurement. Expanded interaction checks, types, browser keyboard behavior, and performance must pass before this candidate is treated as integrated. No unrelated PR feature or release is authorized by the size approval.

The applied structured-text fix passes all 94 focused reconciliation, motion, and SVG-surface tests, including four new ordinary/tween regressions, and root TypeScript. Fresh official builds change seventeen of 151 entries. Against the preserved pre-motion-cleanup bundles, ordinary gzip additions range from 0.016 to 0.048 kB and motion adds 0.089 kB; against the committed cleanup head, the text fix's motion addition is 0.091 kB. These are fresh measurements, not the earlier prototype estimates. Combined known baseline costs are now DOM 0.278 kB, React line 0.322 kB, and interactive legend 0.613 kB. Final complete size accounting, approved ceiling updates, motion regression integration, and text-fix performance checks remain unfinished. No release claim follows from focused test success.

The user approves the reviewed readiness-size decisions: combined correctness costs, combined geographic cost, and the reported structured-text prototype costs. This supersedes the earlier isolated geographic allowance and the zero-growth blocker for those reviewed fixes, not arbitrary new features or unchecked final totals. Performance, fast CI, and separate release approval remain required. The structured-text fix is now applied locally in both SVG reconcilers, preserving the committed unmatched-child cleanup. Final combined measurements and validation must still be completed before readiness.

A mixed-node identity traversal (--mixed in the diagnostic) removes the prototype's separate element index by assigning identity slots across the complete next child-node snapshot. Non-elements receive no keyed identity; element tag counts remain element-only. All five text cases and duplicate-key cleanup/reordering pass, but the local motion build is 69,077 minified / 23,139 gzip bytes versus current 68,977 / 23,087, adding 52 gzip bytes. This is larger than the compact variant and is rejected before broader verification. It changes no production source, official budgets, or CI work.

The stronger motion cleanup comparison uses sixty warmups and forty samples in each of eight fresh Chromium contexts, alternating order across four pairs. All final SVG digests match and no queued frames survive destroy. Pooled synchronous medians are 53.30 ms before and 52.70 ms after; render plus controlled frame-work medians are 55.65 and 55.00 ms. First/second-half synchronous medians differ by at most 0.35 ms per trial, without the previous late-trial step down. One pair is slower after the change and three are faster, so no general speedup is claimed. This supports retaining the narrowly scoped cleanup optimization alongside the 62 passing motion tests, root TypeScript, and all-entry no-growth comparison, not complete-candidate performance clearance. Raw evidence is /private/tmp/charts-motion-unmatched-steady.json; the .mjs driver now specifies the stronger parameters. Routine CI remains unchanged. The separate text prototype and combined-size blockers remain.

The local motion cleanup candidate completes six alternating before/after Chromium 151.0.7922.34 pairs using the actual official minified motion consumer bundles. Each fresh browser context runs three warmups and twenty measured updates of 1,000 keyed dots alternating between two prebuilt scenes, with 100 ms tweens advanced through controlled frame timestamps. All twelve final SVG digests match, every renderer has one SVG root, and destroy leaves no queued frames. The low-level surface intentionally leaves its SVG in the host; the harness removes the host separately and does not claim surface destroy clears DOM. Pooled synchronous-render medians are 64.25 ms before and 63.75 ms after, with paired differences in both directions. Samples fall substantially late in each trial, so three warmups do not establish stable steady-state timing. This is not proof of unchanged complete animation cost or a cleared performance gate. Raw samples and the reproducible driver are preserved at /private/tmp/charts-motion-unmatched-perf.json and .mjs. The runtime candidate remains local pending stronger timing evidence.

The motion unmatched-child change is now a local runtime candidate, separate from the unlanded text prototype. All 62 existing motion tests pass. Fresh official consumer builds before and after compare all 151 entries: 150 are byte-identical, and charts-motion-svg-renderer.js shrinks five minified and two gzip bytes. Exact prior bundles are preserved at /private/tmp/charts-motion-unmatched-before.5GfBHe/bundles. No limits, dependencies, entry sources, or CI jobs change. This candidate still needs type and performance verification before integration, and does not fix the text defect or clear the overall candidate size/performance gates. Root TypeScript also passes with the candidate; performance verification remains.

The diagnostic motion-only unmatched-child variant saves five minified and two gzip bytes versus unchanged source in the local motion entry build. Combined with the compact text prototype it saves five minified but zero gzip bytes versus that prototype, leaving the same 46-byte local gzip growth. All five text mechanism cases pass with the combined variant. An additional duplicate-key/reorder case passes with both unmatched-only and combined variants: two old rects sharing a key become one updated rect, the matched circle keeps its identity, and final child order and attributes match the new markup. This is a narrow diagnostic result, not the full motion suite, official entry comparison, or performance proof. No variant is integrated.

A compact motion text prototype replaces the sibling-removal traversal with a snapshot of current.childNodes, preserving safe removal while iterating. All five dedicated mechanism cases still pass. A controlled local esbuild comparison of charts-motion-svg-renderer.ts gives current 68,982 minified / 23,089 gzip bytes, original prototype 69,085 / 23,142, and compact prototype 69,064 / 23,135. This saves 21 minified and 7 gzip bytes versus the prototype, but still grows 46 gzip bytes versus current source, so it is not integrated. The harness's --size mode uses its own explicit esbuild settings, not the complete official 151-entry configuration or accepted budget check. These figures do not replace the recorded official prototype cost or clear any size gate. The snapshot also allocates an array, so no performance improvement is claimed. Production files remain untouched.

Firefox 153.0 and WebKit 26.5 now confirm the same five motion-driver cases using --browser --engine=firefox and --browser --engine=webkit. Each engine is checked on unchanged source and the in-memory prototype. All five prototype cases pass, the same four defects reproduce on unchanged source, and the cancellation case passes on both. No page errors occur in any run. Together with Chromium this closes the three-engine SVG DOM mechanism check for the preserved text-transition prototype, not a published renderer, paint, natural frame scheduling, or performance claim. The size blocker remains unchanged.

The same five motion-driver diagnostics now run in Chromium 151.0.7922.34 through the harness's --browser mode, with and without --prototype. All three immediate text transitions and the completed timed exit reproduce their current-source defects and pass with the prototype. The halfway cancellation and subsequent keyed update pass on both. No page errors occur. This uses real Chromium SVG DOM and controlled frame timestamps, with the actual driver bundled for the browser. Hosts are detached and this is not paint, screenshot, natural frame scheduling, cross-browser, or performance evidence. It closes only the native Chromium DOM regression checks for these five cases. No routine CI work or production runtime changes are added.

The motion diagnostic now also verifies a keyed text child inside a marks group, with a real 100 ms tween exit. Both current source and prototype retain the child at 0 and 50 ms, with opacity strictly between zero and one halfway through, then remove it at completion. Current source loses the replacement direct text; the prototype preserves it. Cancelling at 50 ms cleans up the exiting child, then updating back to a keyed tspan produces exactly one child with the latest text on both versions. All cases preserve the parent text identity and leave no queued frames. These checks close the specific deferred exit and cancellation scenarios in the preserved diagnostic, not every motion interruption policy or real-browser/performance gate. The runtime prototype remains unlanded under the outstanding size constraint.

Dedicated motion-driver diagnostics now reproduce all three structured-text failures on current source: tspan to direct text becomes empty, direct text to tspan retains the old text, and mixed prefix/suffix text remains stale. The preserved prototype passes all three exact-markup assertions while preserving the existing text element and retained keyed tspan identity. The reproducible driver is /private/tmp/charts-ready-motion-text.mjs; run with and without --prototype. It bundles the actual private motion driver with a diagnostic export and applies the preserved patch only in compiler memory. No production source or public API changes. These arbitrary text children have no scene timing context, so this proves immediate reconciliation, not deferred exits, interrupted animation, browser behavior, or performance. The prototype still fails the size constraint and is not integrated.

Focus-factory purity annotations leave all 151 consumer bundles byte-identical. The interaction router explicitly references all four built-in strategies for string-name resolution and containment behavior, so annotations cannot remove those used strategies. The no-op annotations are removed. Replacing only the string-name switch with a null-prototype routing table saves 36 minified bytes in 25 affected entries but grows all 25 by 11 to 29 gzip bytes. This variant is rejected at the size gate, before any behavior or speed claim, and the original router is restored. Exact pre-change bundles are retained at /private/tmp/charts-focus-pure-before.1HOjiE/bundles. No public focus mode, containment behavior, budget, or dependency is changed.

A bounded GitHub refresh now finds eleven open PRs and the same eight open issues. The new proposals are #162 idle brush/zoom hover passthrough at b32fb23e, #163 a Gantt catalog recipe at e31e62ae, and draft #164 heatmap grid focus at f6c3e54a. These are not merged capabilities or silently added 1.0 requirements. #162 explicitly reports host/control bundle growth and widened limits, with real-browser verification absent. Draft #164 reports ordinary DOM +41 gzip bytes and leaves a DOM-only keyboard protocol versus host-neutral behavior unresolved. Neither is accepted under the current constraints. #163 declares no core runtime changes and needs its own source, catalog, documentation, and browser review before any readiness claim.

PR #161 advances from 1fc13b25 to 713ea36a only by adding the decorative friction report. The already integrated dash-style changes are unchanged. Paginated inline comments return no additional feedback. Its new finding describes main's old state/focus rejection, not this local candidate: inline states now preserve semantic ownership without interaction targets, and inferred focus-filtered marks are rejected through composite types. All 34 focused decorative/composite/focus tests pass again. Existing F-218 owns this evidence, so the stale F-307 report is not copied as a duplicate. The final refresh confirms #161's reviewed head and #153's unchanged aa7a5e1a head. No PR, issue, remote branch, or release is modified by this review.

A shared initial/live tick-opacity callback experiment passes all 29 focused layout and state tests, retaining isolated callback contexts and focus updates without rebuilding the chart. It grows 73 gzip entries out of 74 changed consumer bundles, adding 12 minified bytes in most entries. The candidate therefore keeps the existing initialization and live-focus paths, with the experiment reverted and current-source bundles regenerated. This confirms the scene callback path has a wide retained footprint, not that callback unification is an accepted size optimization. Exact pre-change bundles are retained at /private/tmp/charts-tick-context-before.86cuLg/bundles.

The exact candidate at 3ad1818f passes the complete twelve-tarball build again after unmatched-child reconciliation and restoration of the imported size ceilings. Packed runtime exports, portable declaration emission, downstream consumers, seven framework adapter checks, unified exports, bare React Native Metro, and Expo Metro pass. These remain coordinated 0.18.0 candidate tarballs, not final versioned 1.0 artifacts, registry publication, provenance attestations, or native-device validation. Previous tarballs and their manifest are preserved at /private/tmp/charts-ready-artifacts-before.vsS2EI/artifacts; the refreshed artifacts and integrity manifest are in .release-artifacts. This refresh does not clear the separate size check, which still fails restored limits.

A complete rebuilt size comparison at 211faf85 checks all 151 matching consumer entries against clean baseline 327f488f, with identical lockfiles, unchanged entry source, Node 24.18.0, esbuild 0.27.7, and TypeScript 6.0.3. Seventy-seven entries grow in gzip and 74 are unchanged in gzip; none is smaller than baseline. Current combined costs include static SVG +46 bytes, DOM host +262, React line +288, decorative line SVG +317, interactive legend +573, geographic SVG +80, and polar gauge SVG +212. These fresh measurements supersede earlier combined totals; local savings do not establish compliance. Full before/after raw and gzip sizes and SHA-256 bundle identities are saved in benchmarks/bundle-size/1.0-readiness-comparison.json.

This audit also identifies six widened ceilings inherited from imported commit 265b20ed, despite earlier notes treating budgets as unchanged. Geo, polar arc, gauge, radial labels, radial bars, and polar line/scatter ceilings are now restored to baseline values. The measurement script differs from baseline only by the validation-import guard, not entry definitions or build options. The actual --check correctly fails the outstanding limits. The user's isolated geo +35-byte allowance remains recorded, but the combined +80-byte geo cost exceeds it and does not authorize broader ceiling changes. No runtime code, dependency, locked baseline, or CI job changes in this audit.

A representative-only navigation ordering experiment reproduces the grouped-y failure before its change and passes all seven focus tests afterward, including the original input order remaining unchanged. It retains the existing choice of representative within each coordinate group, then orders representatives by mapped focus coordinate. The string-key variant grows all 25 affected entries by 2 to 10 gzip bytes. Numeric coordinate keys still grow all 25 by 1 to 9 bytes, including DOM host +3 and React line +8, and retain a second sort rather than proving unchanged navigation cost. Both variants and the temporary regression are removed. This does not resolve PR #160; a complete fix still needs compliant size and performance evidence. Pre-change bundles are retained at /private/tmp/charts-group-navigation-before.36Hh4P/bundles.

Ordinary SVG reconciliation now tracks unmatched children directly. The set starts with the complete old child snapshot, including duplicate keys, and removes matched retained elements; cleanup visits only the unmatched set. Detached definition replacements still skip exit handling, and unmatched children retain their existing immediate/deferred removal policy. All 90 focused reconciliation, SVG surface, and motion tests and root TypeScript pass. Of 151 consumer entries, 17 shrink by five minified bytes and 4 to 10 gzip bytes; none grows. DOM host saves 4 gzip bytes and React line saves 9. The fresh standard raw-scatter browser check passes both source counts without correctness failures or recovered retries, and ten soak cycles add zero DOM nodes or listeners. Six alternating before/after 10,000-point update:same production-bundle pairs use fresh contexts, three warmups, and twenty samples per trial. All twelve trials have matching output and digests. Aggregate medians are 43.7 and 43.8 ms, with individual deltas in both directions; this is not a speedup claim or a cleared complete-candidate performance gate. Evidence is retained at /private/tmp/charts-unmatched-pair.json and its .mjs driver; exact pre-change consumer bundles and stress builds are retained at /private/tmp/charts-unmatched-before.ng65nn. The unchanged pre-edit stress bundle hash matches the previously recorded candidate hash 294ddcdd61f1f5c72c0a570e165cc6f1c2ccb0f443269543ad9cffba4ca9d6fc. The post-edit hash is 676a78fa2caae7d41276ba9cb83ead44006e23af17c9ec4463ad598e1b772d28. Combined growth versus main remains unresolved, and no budget or CI job changes.

The refreshed first-party standard Chromium conformance run at 084f3fa5 passes all 188 layout cases and all 22 interaction cases, with no case filter or shard. Node 24.18.0 and Chromium 151.0.7922.34 run on Apple M5 Pro/macOS. The complete result is .benchmark-output/conformance/results/plot-catalog--first-party.json, created at 2026-10-01T01:22:08.813Z, SHA-256 409f40a5364212ff739c35e0a4b767705dcc1334d7f7a22fb684008e2cd1933d. The protocol covers geometry, containment, accessible naming, revision updates, and the catalog's interaction scenarios across viewport/theme variants. Its comparative measurement list is empty by design. This refresh includes the SVG allocation change and the decorative type correction, but does not prove every adapter, native device, unresolved text transition, size, or timing gate. No production source changed while the run was active, and no CI job was added.

A fresh validation run at 084f3fa5 passes all 2,208 unit tests across 301 files, root TypeScript, and the documentation contract for 103 pages, 55 catalog examples, 32 runnable groups, and 8 standalone examples. The unit suite runs alongside browser conformance and takes 23.98 seconds locally; this is neither an isolated speed comparison nor hosted CI timing evidence. Browser conformance is tracked separately and does not replace packed-package validation or the unresolved size and performance gates.

The keyed-child allocation review identifies a cleanup boundary: the identity map overwrites duplicate old keys, while the retained-element collection still lets cleanup remove the obsolete duplicate. Iterating only remaining map values would lose those elements. Two additional tests now verify cleanup, reordered paint order, surviving circle identity, and updated attributes with ordinary updates and zero-duration animation. All 90 focused reconciliation, SVG surface, and motion tests pass. The allocation shortcut is not implemented; this adds validation only. All 151 consumer bundles remain byte-identical to the pre-experiment candidate, and no routine CI job is added.

An attribute-list experiment replaces the next-element name array and value lookups with its existing attributes collection. The ordinary version passes 88 reconciliation, SVG surface, and motion tests but grows ten gzip entries despite saving 24 minified bytes in each affected entry. Removing the now-unreachable null-value branches saves 44 minified bytes in all 17 affected entries, including DOM host -10 gzip and React line -18, but still grows Delaunay DOM by 3 gzip bytes. Both variants are rejected under the per-entry zero-growth limit. The original runtime is restored, with no performance improvement claimed from unmeasured experimental code. Exact pre-change bundles are retained at /private/tmp/charts-attribute-map-before.k2yIYd/bundles.

A fresh six-pair scatter comparison at 9af51388 includes the SVG attribute allocation reduction. Baseline production revision 327f488f and candidate run in alternating order, with fresh browser contexts, three warmups and twenty samples per trial. All twelve 10,000-point update:same trials pass the matching geometry, output, and digest assertions. Chromium 151.0.7922.34 medians are 43.10 ms baseline and 43.85 ms candidate, a 0.75 ms or 1.74% increase. This does not clear the no-regression gate. Absolute timings differ from earlier runs, so those standalone timings are not mixed into this comparison. Exact revisions, production bundle SHA-256 hashes, samples, and correctness output are retained at /private/tmp/charts-ready-exact-stress-after-allocation.json, with the driver at /private/tmp/charts-ready-exact-stress-after-allocation.mjs. The fresh standard raw-scatter run also passes both 1,000/10,000-point cells without correctness failures or recovered retries. Its ten-cycle soak adds zero DOM nodes and listeners; that lifecycle result is not a timing clearance.

A text-transition fix prototype now visits non-element children in their proper order while retaining keyed elements and the leaf-node fast path. Four ordinary/tween regressions reproduce the failures before the change and pass afterward: both plain-text/tspan directions, mixed prefix/suffix text, retained tspan identity, and an exiting child kept until its fade finishes. All 92 focused reconciliation, motion, and SVG surface tests and root TypeScript pass. The motion walker receives the same structural correction, but dedicated motion text-transition cases and real-browser performance verification are not yet complete. Equivalent builds grow 17 entries: ordinary entries add 15 to 43 gzip bytes, including DOM host +15 and React line +28, while motion adds 88. This is an unapproved cost, so all prototype source and test changes are removed. The patch is preserved at /private/tmp/charts-ready-text-transition-fix.patch, and exact before/after consumer bundles at /private/tmp/charts-text-fix-before.T1lgVc/bundles and its after sibling. Current-source bundles are regenerated after restoration so the workspace outputs do not retain the rejected prototype. This defect remains open.

The shared SVG tree-walk component of #153 is now measured in isolation against this candidate, retaining the verified allocation-free static attribute update path. It saves 2,957 minified and 1,024 gzip bytes in the motion entry, but adds 421 minified and 121 gzip bytes in ordinary DOM host. Sixteen entries grow in gzip, including React line +102. The integration is reverted rather than trading ordinary-host growth for optional motion savings. The pre-experiment entry set is retained at /private/tmp/charts-shared-reconcile-before.49MbaC/bundles.

Two concrete text-transition regressions fail on both current code and the isolated shared reconciler. Replacing <tspan>old</tspan> with direct new leaves empty content; replacing direct old with <tspan>new</tspan> leaves the stale old text beside the new child. The other 88 focused reconciliation, motion, and SVG surface tests pass during the experiment. This confirms the review finding remains an existing correctness defect, not a solved refactor benefit. The source reproduction is retained at /private/tmp/charts-ready-text-transition-repro.mjs. A complete fix must preserve keyed identity and deferred exits, verify ordinary and motion paths, and meet the same size/performance constraints. No failing regression or experimental runtime edit is retained in the candidate.

PR #153 is re-reviewed at unchanged head aa7a5e1a. Its aggregate Vite savings do not establish per-entry compliance: the PR description explicitly acknowledges small-entry growth and adjusted ceilings. Those budget changes are not accepted for this candidate. Paginated inline feedback confirms a valid element/text reconciliation defect that also exists on the PR base; the contributor intentionally leaves that behavior unchanged in the refactor. It must not be dismissed as fixed by shared reconciliation code.

An isolated equality-helper extraction from #153 passes 31 focused tests, including primitive/Date identity, invalid Dates, NaN, signed zero, and Date versus timestamp behavior. Equivalent complete-entry builds save 102 minified and 37 gzip bytes in DOM host, but grow 36 other entries, so the change is rejected. Keeping configured-scale equality separate and sharing only the interaction/tooltip copies still grows React compact line by 5 gzip bytes, React line by 3, and scale handle by 4. That variant is also removed, with no production edits retained and no budgets changed. Pre-experiment consumer bundles are retained at /private/tmp/charts-value-sharing-before.T7NSHW. The remaining #153 components need independent review and measurements rather than approval based on aggregate savings.

A fresh full test run at 816f5da3 passes 2,203 tests across 301 files. The GitHub backlog refresh finds eight open issues and eight open PRs, with the previously reviewed heads unchanged. In addition to the focused state issues, the remaining issues include #132 crosshair label backgrounds, #128 pattern resources, #108 Flint backend support, and #106 example embedding. These feature/integration requests are not silently folded into the fixed state reports or treated as resolved by 1.0 package verification.

The audit also catches a test-only CI classification gap: .type-test.ts and Octane .test.tsrx files were still counted as production changes. The shared test boundary and Git revision exclusions now recognize both. Six failing regression checks reproduce the gap before the correction; all 27 focused boundary/workflow/provenance tests pass afterward. Validation files no longer change the measured input digest or revision, while ordinary runtime modules still do. A test-only PR retains full static checks without selecting comparison or stress; mixed Octane test/runtime changes select both. Production bundle imports of these validation files are rejected rather than excluded silently. All 151 measured consumer entries build with the stronger guard, and the standalone eighteen-test CI contract passes. This changes only tooling and tests, adds no published runtime code or CI jobs, and does not clear the combined size gate. Comparison artifacts still need regeneration with current production-only provenance before final release verification. The full suite after this tooling correction passes 2,206 tests across 301 files in 13.13 seconds locally; this is not a measured hosted CI duration.

The remaining known decorative/focus type mismatch is now corrected locally. whenFocused retains type-only focus-filtering metadata, and compositeMark preserves it through nested children. decorative rejects those inferred inputs without changing ordinary marks, inline-state marks, or the runtime validation boundary for JavaScript/custom/widened marks. Three direct and nested type regressions fail before the change and pass afterward. Root TypeScript and 34 focused decorative/composite/focus runtime tests pass. Of 151 consumer bundles, 150 are byte-identical, and the decorative line entry has only minified symbol renaming with identical raw and gzip size. No measured entry grows. Canonical documentation and generated copies are synchronized; the contract passes for 103 pages, 55 catalog examples, 32 runnable groups, and 8 standalone examples. The complete twelve-tarball artifact build passes again, including declarations, framework adapters, unified exports, and Metro. An isolated installed consumer reproduces all three type failures on the previous tarball and passes with the uniquely named updated tarball under strict TypeScript 6.0.3 and skipLibCheck: false. The fixture is retained at /private/tmp/charts-ready-octane-browser.4UeXIL/decorative-types.ts, with charts-decorative-types-0.18.0.tgz and the updated lockfile. The original hydration tarballs and lockfile are preserved separately. PR #161 remains open at 1fc13b25; this local type fix is not a merge or release claim.

The exact candidate at e68f1670 now passes the complete twelve-tarball artifact build again: runtime exports, portable declaration emit, downstream compilation, seven framework package checks, unified exports, and bare React Native and Expo Metro. These are still 0.18.0 candidate artifacts, not final 1.0 artifacts or a publication claim.

Octane SVG now also passes an isolated installed-package real-browser hydration check in Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. The consumer uses the candidate core/scales tarballs, Octane 0.1.13, Vite 8.1.5, and Node 24.18.0. Vite renders the server fixture without browser globals, and its separately compiled client bundle imports installed package modules, with an assertion excluding all workspace paths. Hydration preserves the server host, SVG, and actual line path identities. A real button changes the data from [2, 4] to [1, 3] under a fixed [0, 4] domain, and the same path changes exactly from M0,130L480,0 to M0,195L480,65 while the accessible name updates. Unmount removes the app content. All engines report no page errors or console errors/warnings. This closes the installed Octane SVG hydration gap, not every adapter lifecycle or native-device gate. The consumer, lockfile, source, verifier, release manifest, tarball SHA-256 identities, module inventory, and results are retained at /private/tmp/charts-ready-octane-browser.4UeXIL.

Two further bounded experiments are rejected. Querying the next SVG element directly in the motion reconciler passes all 62 motion tests, but grows the motion entry by one gzip byte and is reverted. For grouped-y navigation, numeric representative keys avoid unnecessary number-to-string conversion while an axis-aware comparator passes the reproduced top-to-bottom ordering regression and all seven focus tests. The complete-entry comparison still grows 25 entries, including DOM host +11 gzip and React line +10, so that runtime variant and temporary regression are also removed. Neither is a shipped fix, and the navigation defect remains open. The pre-experiment consumer bundles are retained at /private/tmp/charts-motion-attributes-before.0e653U/bundles.

SVG attribute reconciliation now queries the next element directly when removing stale attributes, instead of allocating a Set for every node. All 151 measured consumer entries are compared against the pre-change candidate: 26 change, none grows in gzip, and DOM host and React line each shrink by 17 minified and 13 gzip bytes. The 25 existing reconciliation and SVG surface tests and 124 motion/renderer tests pass. An additional attribute regression verifies identity, removals, new attributes, empty values, and qualified names; all 13 reconciliation tests pass afterward. The standard raw-scatter check passes both cells without correctness failures or retries, and the ten-cycle soak has zero DOM-node and listener deltas. Six alternating pre-change/current production-bundle pairs, with fresh contexts, three warmups and twenty samples per trial, have medians 38.1 and 38.0 ms for 10,000-point update:same. Every trial has matching output and digests. This supports unchanged timing for this edit, not a cleared full candidate performance gate. Raw evidence is retained at /private/tmp/charts-reconcile-pair.json, with the pre-change production bundles at /private/tmp/charts-reconcile-before.8JNSjF. The combined size increases versus main remain unapproved; these savings do not hide or clear those outstanding costs.

A Chromium CPU diagnostic now narrows the raw-scatter investigation. It uses the same extracted stress timing cell, production bundles, 10,000-point update:same workload, and matching output assertions for baseline and candidate. At a 100 microsecond sampling interval, profiled update medians are 40.0 and 40.2 ms. Attribute reconciliation, template parsing, child reconciliation, and forced layout dominate both profiles. Their generated function bodies are unchanged apart from minified symbol names, and attribute reconciliation self time is 262.936 ms baseline versus 252.175 ms candidate over the whole profile. This is diagnostic evidence, not a performance gate: sampling adds overhead, the profile includes setup and output checks, and a single pair cannot overturn the six-pair unprofiled +2.3% result. No state-resolution hotspot appears among the leading samples. The next investigation is the DOM reconciliation allocation path, not another speculative state rewrite. The diagnostic and raw profiles are retained at /private/tmp/charts-ready-scatter-cpu.mjs and /private/tmp/charts-ready-scatter-cpu.json.

PR #161's dashed-stroke type correction is integrated locally. The pinned-dot test reproduces TS2353 on the pre-fix public type while runtime application and restoration already pass. Adding the missing property to dot, bar/rect, area, and text state types makes root TypeScript pass. All thirteen SVG surface tests pass, and all 151 measured consumer JavaScript files have identical SHA-256 hashes before and after this type-only change. Root docs are updated and their generated copies synchronized. The PR is not merged, and packed declarations still need verification of this latest public-type change. The documentation contract passes for 103 pages, 55 catalog examples, 32 runnable groups, and 8 standalone examples. The refreshed artifact build at ab3e6cfa passes packed declaration emit, downstream compilation, runtime exports, seven framework adapters, unified package validation, bare React Native Metro, and Expo Metro. All twelve 0.18.0 tarballs and their integrity manifest are refreshed. This validates the latest package set, but the downstream fixtures do not yet explicitly instantiate all six dashed-stroke state-style types. A separate direct current-source reproduction also confirms PR #160 is still relevant: grouped-y navigation returns the lower-left row before the upper row. That navigation fix remains unintegrated and unverified against size/performance. An isolated installed-tarball consumer now explicitly compiles dashed-stroke assignments for dot, bar, rect, line, area, and text state styles, plus a datum-typed dot callback, with TypeScript 6.0.3, strict checking, and skipLibCheck: false. Its uniquely named tarball and lockfile integrity identify the refreshed ab3e6cfa artifact rather than a workspace import. The source is retained at /private/tmp/charts-ready-angular-browser.QIU8i1/state-types.ts. This closes the six-type downstream coverage gap recorded above. Testing the exact PR #160 comparator reproduces the failing row-order regression before the fix and passes all seven focused tests afterward. Equivalent complete-entry builds add 32 minified bytes in 25 entries, including DOM host +16 gzip bytes and React line +17. The proposed runtime change and temporary regression were removed from the candidate rather than accepting this growth. The defect remains open, with evidence for a smaller implementation still required; no navigation fix is claimed or merged. Two smaller grouped-y navigation experiments also fail the constraint. Retaining raw x/y tie breaks behind one primary-axis variable adds 21 minified bytes and grows gzip in 25 entries, including DOM host by 13 bytes. Replacing its grouped representative Map with Set-based filtering lowers that to 17 minified bytes and DOM +12 gzip, but still grows 25 entries. Both variants are discarded; the original runtime remains unchanged.

PR #161's decorative-type report is partly superseded by this candidate: decorative() now preserves ordinary inline states, including composite area states, without adding interaction points. All seven decorative tests pass, including datum callback identity and series paint. Focus-only whenFocused geometry is still rejected directly and inside composite scene geometry, while its mark type does not encode that restriction. This remaining type boundary needs an explicit compatibility decision; the report must not be treated as entirely fixed or as evidence that inline states still fail here.

A bounded GitHub refresh confirms main remains b215626e and the latest published release remains v0.18.0. PRs #155, #158, and #159 are still open at their previously reviewed heads. PR #155 has failing static, line-comparison, and aggregate CI checks; #158 and #159 expose security/review checks but no completed full CI evidence for their current heads. No merges or publication occurred in this audit. Newly opened PR #160 (7f7e4288) corrects grouped-y keyboard navigation ordering, and #161 (1fc13b25) adds missing dashed-stroke state-style types. Their source diffs are reviewed, but neither is integrated or verified locally yet. PR #161 also reports decorative marks accepting types that the runtime rejects, which needs comparison against this candidate's existing decorative-state changes before assuming it remains unfixed.

  • Main at the start of this audit: 327f488f46463408e91eef4828d54f45017f717d.
  • Latest published release on 2026-09-30: 0.18.0.
  • PR #157 merged into main as b215626e4730ff1edd82995cdf9d73253b0fd1f1. Issue #156 is closed. Its static, comparison, stress, and aggregate CI checks passed at reviewed head f842e7a455cbd1e2fe81ecd3b9ab7de912c0988e.
  • Existing API harmonization roadmap is complete, but the Alpha stability policy has not yet defined the 1.0 compatibility promise.
  • PRs #155, #157, and #158 have been reviewed at source level and integrated locally for combined verification. Their GitHub check summaries alone do not prove that the complete validation graph ran.
  • Combined packed-package verification passed on 2026-09-30, including declaration emit, downstream declaration compilation, bare React Native and Expo Metro, runtime exports, and seven framework package checks.
  • Group state ownership has a verified failing regression on the old resolver and passing tests on the new resolver. Chromium, Firefox, and WebKit checks confirm one painted group per unmatched datum, unchanged leaf geometry, focus restoration, animation-frame cancellation, and no page errors.
  • In 11 interleaved trials with 1,000 three-leaf candles, median state resolution was 0.864 ms with group ownership versus 1.138 ms with child inheritance. The style resolution count fell from 2,997 to 999 per update. This measures the scene resolver, not complete browser hover latency.
  • Earlier local map/polar work is preserved on taren/focus-state-batch. Existing PR #158 provides the implementation under review for this audit.
  • The initial full unit run passed 2,180 tests and failed one public callback contract check. The new SceneLabel.focusOpacity callback now accepts one context object and is classified as an application callback. All 37 focused callback, layout, and decorative-mark tests pass after that correction.
  • The corrected full unit run passes 2,183 tests across 300 files. The root TypeScript check also passes. These checks do not replace final packed-package and browser verification of the newest focus changes.
  • After indexed ownership and geometry-copy changes, the full unit run passes 2,187 tests across 300 files, and the root TypeScript check passes again. Packed-package validation of this candidate also passes: portable declarations, runtime exports, seven framework adapters, unified package artifacts, bare React Native Metro, and Expo Metro. Native-device checks remain outside this evidence and React Native remains experimental.
  • Tick focus opacity and decorative area ownership pass targeted regressions, including decorative composite marks. Their combined bundle growth remains unresolved, so these changes have not cleared the size gate.
  • The latest size check still fails with unchanged budgets. Relative to the locked baseline, the ordinary static line adds 63 gzip bytes, the DOM host adds 137, and the React line consumer adds 144. These are measured costs, not approved increases.
  • A point-set ownership regression caught an unrelated key inheriting an ancestor's point. Explicit owners now use the same identity rules as singular owners rather than generated-fragment key inference. Exact copied owners and restricted scopes pass along with the unrelated-key regression.
  • Waiting contributor CI runs for PRs #155, #157, and #158 have been approved. PR #158's benchmark run was confirmed in progress after approval. Their eventual results still need inspection before merging.
  • Exact point-set ownership now uses the existing identity index. Five focused ownership tests cover scope restrictions, copied owners, unrelated keys, duplicate-key reference identity, and semantic adoption. In nine interleaved trials, 5,000 copied exact owners resolved in a median of 0.180 ms versus 81.675 ms with the initial scanning implementation. This does not measure complete browser latency or prove every performance gate.
  • Dot and label state geometry now update a single fresh node copy rather than cloning that node twice. A regression verifies geometry changes, base-scene immutability, and focus restoration. This optimization does not clear the bundle gate.
  • The three approved PR benchmark workflows are in progress. Their conformance monitoring workflows completed as skipped, not passed conformance evidence.
  • PR #155's completed workflow failed comparison provenance because its sole changed file, adapter.test.ts, changed the recorded production input digest. Test-only changes also selected browser comparison and stress jobs. Local tooling now distinguishes package tests from runtime inputs while keeping full static validation. Runtime changes still select comparison and stress. Bundle builders reject imports of package test files. All 24 focused tooling tests pass. Comparison artifacts still need honest regeneration with the new production-only provenance rule before this tooling can land.
  • After the tick resolver and CI classification changes, the complete unit run passes 2,189 tests across 301 files. TypeScript passes. The measured source bundles also pass the new test-import guard, but still fail size budgets.
  • Reusing the tick-label value resolver reduced the ordinary static line's measured increase from 63 to 45 gzip bytes. The React line consumer still adds 140 gzip bytes. The unchanged size budgets still fail.

Latest legend evidence

Interactive color legends now have opt-in hover: 'series' for pointer and keyboard emphasis. The host keeps inline-state matching separate from real interaction focus. Series lookup stays in the optional legend module. Unit tests preserve pinned focus, unchanged tooltip text, and real tick-label focus. SVG and motion browser fixtures pass in Chromium, Firefox, and WebKit, including unfocused hover, keyboard emphasis, restoration, and host teardown.

The full unit run passes 2,191 tests across 301 files. TypeScript and the documentation contract pass after making host control contexts generic in the chart datum and axis values. The new legend handlers allocate only when hover is enabled for a visible item. Final package validation of this new protocol is recorded below.

Package verification of the new state-focus protocol now passes, including portable consumer declarations, packed runtime exports, seven framework adapters, unified artifacts, bare React Native Metro, and Expo Metro. A Canvas unit regression passes for pointer and keyboard opacity paint and null-focus restoration. Update regressions pass for new datum ownership, disabling hover, hiding the emphasized series, and removing the legend entirely.

Canvas pixel checks now pass in Chromium, Firefox, and WebKit for unfocused hover restoration, pinned-focus restoration, keyboard emphasis, unchanged tooltip text, and host teardown, with no page errors. The fixture uses z as the dot's semantic series and default color channel. A failing visibility regression additionally exposed missing color-series ownership metadata on these dots. That metadata is now retained; independent per-point colors remain separate from semantic series.

Unit regressions now verify independent emphasis through interrupted data motion, restoration afterward, and animation-frame cleanup on teardown. A reduced-motion regression verifies immediate emphasis and restoration without requesting an animation frame. These do not prove exact state-tween timing or replace final browser verification of the full combined candidate.

The unchanged size check still fails. Sharing the x/y tick-label construction removes duplicated code while preserving their geometry and baseline behavior. With this change and the dot visibility correction, static line SVG adds 46 gzip bytes, the DOM host adds 277, and the React line consumer adds 308 against locked baselines. These costs are not approved. The tick-layout suite passes all 24 tests, but the size gate remains open.

The latest full unit run, including Canvas and update regressions and the dot visibility correction, passes 2,195 tests across 301 files. TypeScript passes. The package run above predates the dot visibility metadata correction, so the final release artifact audit must still verify that last change.

After the motion regressions and shared tick-label construction, the complete unit run passes 2,197 tests across 301 files. TypeScript and the whitespace check pass. This does not clear the remaining package, browser, performance, size, or release-artifact gates.

Custom-renderer protocol tests verify supported and unsupported independent state focus, restoration, teardown, and no real focus callbacks. Mixed SVG and Canvas tests verify forwarding emphasis and restoration to every layer; the composed surface advertises support only when every layer supports it. The focused renderer run passes 121 tests across three files. TypeScript passes, and the complete unit run passes 2,199 tests across 301 files.

Packed-package verification now includes the dot visibility correction and shared tick-label construction. Portable declarations, runtime exports, seven framework adapters, unified artifacts, bare React Native Metro, and Expo Metro all pass. Native-device validation is not included in this result.

The first-party standard browser run passes all 188 layout cases and all 22 interaction cases in Chromium 151.0.7922.34 with Node 24.18.0. It checks the catalog before and after revision across the standard viewport/theme matrix, including the catalog's native keyboard, pointer, touch, drag, and wheel scenarios. It does not measure comparative size or timing, test every browser, or replace separate SSR/hydration and export verification. The result is saved in .benchmark-output/conformance/results/plot-catalog--first-party.json.

A temporary major-version rehearsal produces a Changesets plan for all twelve public packages at 1.0.0. The actual checkout remains at 0.18.0. The rehearsal caught stale current-Alpha prose after version synchronization; the release references now retain version-scoped Alpha and stable policies. All nine release-reference tests pass. The documentation contract also passes for all 103 pages, 55 catalog examples, 32 runnable groups, and 8 standalone examples. The complete unit run passes 2,200 tests across 301 files, including 48 focused release-workflow, artifact, status, security, package, and synchronization tests.

The isolated rehearsal validates twelve 1.0.0 tarballs, with packed declarations, runtime exports, seven framework adapters, unified artifacts, bare React Native Metro, and Expo Metro passing. Dependencies were installed offline in that workspace rather than resolving back into this checkout. The rehearsal uses unpublished changesets, so it does not prove GitHub-linked release changelog generation, OIDC publication, registry propagation, or final release provenance. Its artifacts and integrity manifest are retained under /private/tmp/charts-one-ready-rehearsal.BYRIrs/.release-artifacts. All nine release-reference tests also pass inside the versioned 1.0.0 workspace, not just against simulated string replacements in this checkout. The final version-PR artifact gate still requires its exact revision.

The refreshed PR #158 head is ece13f84df11d793700fe1cf529a913d435930cf. Its new commits merge the already-reviewed declaration fix from main and refresh evidence; they do not change the polar/geographic state implementation. The local implementation therefore remains current, but its combined evidence still needs regeneration. A separate version PR #159 consumes only the portable declaration changeset and proposes 0.18.1 for all twelve public packages. It has not been merged as part of the 1.0 readiness work.

Performance audit

Fresh production raw-scatter builds at ab3e6cfa complete both standard source-count cells with zero correctness failures and no recovered retries. The ten-cycle 10,000-dot teardown soak retains zero extra DOM nodes or listeners; its reported JavaScript heap delta is not a zero-memory-retention proof. Six alternating exact same-data update pairs then produce trial-median medians of 37.40 ms for baseline 327f488f and 38.25 ms for the candidate, an increase of 0.85 ms or about 2.3%. Each fresh-context trial has three warmups and twenty samples, with matching source/target digests and output probes across all twelve trials. Node is 24.18.0 and Chromium is 151.0.7922.34. The complete result, including revision identities and raw samples, is retained at /private/tmp/charts-ready-exact-stress-current-pair.json. This repeats the earlier small controlled slowdown and does not clear the performance gate.

The renderer capability error now describes unsupported independent state focus instead of incorrectly naming legends for every host control. All 62 renderer tests pass, including unsupported capability rejection and null-focus restoration. Equivalent complete-entry builds against 200de3cc show no minified or gzip increases: twenty affected entries each save 24 minified bytes and 4 to 14 gzip bytes. DOM host and React line each save 10 gzip bytes, leaving their combined baseline increases at 267 and 298 respectively. This changes only error text, with identical runtime control flow and allocations by source inspection; no timing improvement is claimed. The combined size and performance gates remain open.

Two point-key scan experiments were discarded. Reusing the separator search through a for loop passes the five ownership regressions but adds eight minified bytes in affected entries. A single-search assignment loop removes 13 minified bytes yet increases gzip in nine entries, including DOM host by two bytes. Neither satisfies the per-entry constraint. The original indexed ownership implementation remains, including exact-reference, copied-owner, duplicate-key, and scope behavior; no performance claim is made from these discarded variants.

A fresh size check at 79e7154f still fails unchanged budgets. Rebuilding the retained baseline checkout with the same Node 24.18.0 toolchain reproduces static SVG +46 gzip bytes, DOM host +277, and React line +308. Comparing the generated bundles also shows the combined geographic SVG entry adds 80 gzip bytes, above the separately approved 35-byte increase. Other changed entries include interactive legend +582, decorative line SVG +317, and polar gauge SVG +212. The baseline and candidate outputs are retained in each checkout's .bundle-output directory. These are combined consumer costs, not isolated feature attribution. Source review identifies shared scene changes and the renderer state-focus protocol as separate areas to measure; removing required behavior or increasing budgets is not an accepted resolution.

A state-presence scan experiment replaced recursive Array.some callbacks with direct loops. It was discarded: the DOM host saved one gzip byte, but the React adapter added five gzip bytes and affected host entries added 18 minified bytes relative to the candidate. The original scan is retained. This experiment does not establish a performance improvement and does not clear the size gate.

An esbuild-metafile comparison isolates emitted module changes with equivalent production settings. For static SVG, only scene.ts changes: minified output falls 74 bytes while complete-bundle gzip grows 46. This is a compression regression despite smaller minified output. For the DOM host, emitted module deltas are renderer +252 bytes, mark-state +149, point ownership +115, SVG surface +41, focus layer +15, and scene -70, totaling +502. Per-module gzip costs cannot be added to infer compressed consumer size. The diagnostic is retained at /private/tmp/charts-ready-bundle-attribution.mjs; its final bundle totals reproduce the standard measurement exactly. This evidence separates the scene compression problem from the host protocol costs without removing required behavior or claiming those costs have been fixed.

Factoring tick dx/dy additions outside their x/y conditionals preserves the existing arithmetic grouping and passes all 24 tick-layout tests. A complete entry comparison against the unchanged candidate improves gzip in 72 entries, including static SVG by one byte and DOM/React line by four, but increases Delaunay DOM by one byte. It was reverted rather than hiding that entry's growth behind aggregate savings. Production source is unchanged after these two discarded experiments.

The standard TanStack stress suite was run sequentially for baseline 327f488f46463408e91eef4828d54f45017f717d and candidate b2995b26e6e5ce4d51c97903268131713bbe0ac9. The baseline is retained in /private/tmp/charts-one-ready-perf-baseline.JYf28Q with matching pinned dependencies installed offline. Workload definitions, measurement scripts, and TanStack benchmark adapters are unchanged between these revisions. Both runs used Node 24.18.0 and Chromium 151.0.7922.34 on the same Apple M5 Pro.

Both revisions complete all 20 standard cells with no correctness failures. Source counts, prepared counts, canonical input digests, update target digests, and fixed timing sample counts match. All eleven ten-cycle teardown soaks retain zero additional documents, DOM nodes, or listeners after garbage collection. Heap deltas remain reported measurements, not a proof of zero retained JavaScript allocation or GPU/native memory use.

The timing gate remains open. The first pair contains slower candidate scatter timings. Repeating raw line, raw scatter, and interactive scatter in reversed candidate/baseline order also completes all six cells correctly, but several 10,000-dot synchronous updates remain slower across separate runs: same-data update 35.3 ms to 39.6 ms, append 36.4 ms to 40.7 ms, and replacement 32.3 ms to 36.6 ms. These are not approved regressions.

Interleaved diagnostic trials do not establish the same difference. With 10,000 dots, 21 alternating blocks, and five operations per block, initial scene compilation and SVG serialization differ by less than 1%. A mounted diagnostic with both 800 by 400 charts fully visible produces median updates of 34.3 ms for baseline and 34.9 ms for candidate, with identical DOM output. This fixture differs from the stress suite's fresh-context update trials, so it does not clear the repeated stress slowdown or identify its cause. The earlier vertically stacked mounted diagnostic partly clipped its second chart and is not used as equivalent-layout evidence.

Reproduction uses node scripts/stress-chart-libraries.mjs --library=tanstack --profile=standard in each checkout, one run at a time. The reversed-order repeat adds --workload=raw-scatter,interactive-scatter,raw-line. Original full results are retained at /private/tmp/charts-ready-stress-baseline-full-1.json and /private/tmp/charts-ready-stress-candidate-full-1.json; paired summaries are /private/tmp/charts-ready-stress-pair.json and /private/tmp/charts-ready-stress-repeat-pair.json. Diagnostic fixtures and results are retained in /private/tmp/charts-ready-scene-pair.mjs, /private/tmp/charts-ready-scene-pair.json, and /private/tmp/charts-ready-visible-mounted-pair.json. No routine CI jobs or budgets were changed for this audit.

A follow-up uses the exact stress timing function and compiled production bundles in six alternating baseline/candidate pairs, each in a fresh browser context with the same 1,400 by 900 viewport. For the 10,000-dot same-data update, with three warmups and twenty samples per trial, the median of trial medians is 37.85 ms for baseline and 38.65 ms for candidate, a 0.80 ms or 2.1% increase. Source and target digests and output probes match. Results are retained in /private/tmp/charts-ready-exact-stress-pair.json and the diagnostic is /private/tmp/charts-ready-exact-stress-pair.mjs. This more controlled comparison weakens evidence for the larger separate-run slowdown, but does not prove unchanged performance or cover other update, pointer, and animation phases.

Two tick-opacity allocation experiments were discarded after size measurement. Both avoid cloning the cold focus context for constant opacity, but increase measured consumer bundles relative to the existing candidate. The existing implementation is retained, and no size budgets were changed. Logs are retained in /private/tmp/charts-ready-tick-before-size.log, /private/tmp/charts-ready-tick-after-size.log, and /private/tmp/charts-ready-tick-direct-size.log.

Adapter hydration follow-up

A fresh Octane client run passes seven tests across three files. Inspection confirms actual server-rendered Canvas-shell hydration and canvas-node identity coverage, but the SVG client suite has no hydrateRoot regression. The complete adapter gate therefore still needs SVG hydration evidence. A focused export run passes seven tests, covering standalone SVG presentation, focus inclusion, and Canvas/mixed-layer composition. Its rasterization tests mock Canvas contexts, image loading, and toBlob; they do not prove real image decoding, pixel composition, or PNG output in a browser. Browser export validation remains a separate required check, not evidence supplied by those passing unit tests.

An installed candidate consumer now validates real PNG export in Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. The export module is bundled from the isolated consumer's candidate tarball, with no workspace source inputs. Explicit 100 by 50 SVG and Canvas surfaces export at scale 1, decode as actual PNG images, and yield exact expected opaque red, blue, and green pixels. SVG focus is excluded by default and included on request; the Canvas base bitmap exports correctly. All runs finish without page errors or console warnings/errors. The retained verifier is /private/tmp/charts-ready-angular-browser.QIU8i1/export-browser.mjs. This covers hand-authored valid surfaces, not mounted-chart updates, mixed layer pixel composition, portable fonts, or every export format. Those broader export checks remain open. No routine CI job or shipped source changed.

The same installed-package verifier now also proves mixed SVG/Canvas paint order in all three engines: the Canvas bitmap covers the lower SVG layer, then the upper SVG covers Canvas at an overlapping probe. Separate Canvas exports prove focus-layer inclusion and a later focus-free export selecting the stable base bitmap again. All six exports per engine decode with exact expected pixels and dimensions, with no page errors or console warnings/errors. This closes the hand-authored mixed-layer pixel gap, not the remaining mounted chart update, font portability, or additional format coverage.

The installed-package PNG verifier now mounts a real chart with the candidate DOM host and compact scales. It exports a red horizontal line, updates the definition to a blue line at a different y-value, then exports again. Decoded pixels confirm the old position becomes white and the new position is blue; the accessible label also updates. Host destruction removes the SVG surface. These checks pass in Chromium, Firefox, and WebKit without warnings/errors, closing mounted SVG update/export coverage for this deterministic line case. This does not verify mounted Canvas updates, arbitrary fonts, or every chart and image format. No production code, dependencies, budgets, or CI jobs changed.

Mounted Canvas update/export now passes the same installed-package test in all three engines. The verifier asserts a real Canvas scene layer and no SVG, exports the initial red line, updates data and stroke to move a blue line, and proves the changed geometry through decoded PNG pixels and the updated accessible label. Destruction removes every canvas. All ten PNG cases per engine pass without warnings/errors. This closes the deterministic mounted Canvas update/export gap while font portability and additional image-format coverage remain outside this evidence.

The new Octane SVG hydration regression now renders the matching component through the server compiler, hydrates its actual markup through hydrateRoot, preserves the host, SVG, and line nodes, emits no console warnings/errors, and empties the target on unmount. The complete Octane client suite passes eight tests across four files. This is source-level jsdom evidence, not installed tarball browser verification or a post-hydration reactive-update check. No production code or CI job was added; those remaining scopes stay open.

The Octane SVG regression now also drives a real button-triggered useState update after hydration. The accessible label updates while the original host, SVG, and line nodes remain unchanged, with no warnings/errors and complete unmount cleanup. Eight client tests and ten server tests pass. The server and shared component fixtures live under the package's tests/ directory rather than production source. Installed-tarball real-browser verification remains open; this does not clear the complete adapter gate.

The Vue adapter now has a direct server-to-client hydration regression rather than treating a fresh mount as hydration evidence. It renders with Vue's server renderer, mounts a fresh client application onto that markup, verifies SVG and line node identity and no Vue warnings, updates its accessible label without replacing the SVG, and checks unmount cleanup. All four Vue adapter tests pass. The Svelte adapter now also hydrates actual server-compiled component markup. Recovery is disabled, SVG and line identities are preserved, no warnings are emitted, and unmount leaves the target empty. All four Svelte client tests pass; the measured complete suite takes 1.48 seconds versus 1.23 seconds before adding this case, not a general CI latency guarantee. Its separate SSR test passes. Solid now also hydrates server-compiled markup, preserves the SVG and line nodes, updates the accessible label in place, and empties the target on disposal. The test uses matching server component boundaries, Solid's generated hydration bootstrap, and hydratable client compilation. Its three client tests pass in 1.19 seconds locally. Hydration globals are restored after the test. This is test setup, not a change to the shipped adapter. Its separate SSR test passes. These test-only changes add no shipped code or CI job. They do not prove Angular or Octane SVG hydration and do not clear the complete adapter gate.

The full root unit suite at 6d2f8482 passes 2,201 tests across 301 files. That run predates the new Angular hydration regression. With server-rendering and hydration providers enabled on the server, hydration enabled on the client, and the actual server body nodes and integrity marker retained, Angular reports two hydrated components with none skipped. However, the chart SVG is replaced rather than adopted, so the new node-identity regression fails. The adapter's initial [innerHTML] binding is under investigation. No runtime fix has been applied at the time of that failing run.

The local Angular fix removes the live [innerHTML] binding and seeds an empty surface once in ngAfterViewInit. Existing server nodes remain renderer-owned. The initial hydration identity test and existing mount/update/tooltip tests pass, and Angular partial compilation and root TypeScript checks pass. Further verification is ongoing, so the adapter gate remains open. A preliminary comparison of compiled Angular modules against the retained 1.0 rehearsal artifact shows minified bytes 12,914 to 12,899 and gzip bytes 2,982 to 2,979; unminified bytes increase 16,875 to 16,933. This is not a fresh baseline build, a linked application bundle, or a completed performance comparison. Extending the hydration test with an immutable options update reveals that the accessible label stays stale after client change detection. The identity fix therefore does not yet satisfy the complete lifecycle contract. A diagnostic confirms the client uses Angular's browser platform with server mode unset; the update failure remains under investigation rather than being skipped.

The earlier same-process Angular hydration fixture was not valid client isolation: Angular retained its server document, causing the client to operate against server DOM. The corrected regression renders in a separate Node process and hydrates the resulting body in the browser test environment. It verifies that the browser host mounts, preserves SVG and line identity, handles immutable signal-driven options updates, and destroys its application. The original adapter fails identity in this corrected fixture; the lifecycle fix passes. All four Angular SSR, hydration, mount/update, and tooltip tests pass in 1.34 seconds locally. The earlier stale-label observation used manual class mutation; signal-driven updates pass in the corrected fixture.

Fresh before/after Angular partial builds with the same dependencies reproduce the module measurements above: minified bytes decrease by 15 and gzip by 3, while unminified bytes increase by 58. Build logs are retained at /private/tmp/charts-ready-angular-baseline-build.log and /private/tmp/charts-ready-angular-candidate-build.log. The shared core runtime is unchanged by this fix. Linked consumer, browser, and final packed-package verification remain open, and this does not clear the combined size or performance gate.

After explicitly classifying Angular's ngAfterViewInit as a lifecycle service method in the existing callable-surface audit, all six audit tests pass. The complete root unit suite passes 2,202 tests across 301 files, including the corrected Angular hydration test. The audit still rejects unclassified callables. The packed-package run completes successfully: exports, declarations, runtime, bare React Native and Expo Metro, seven framework packages, and the unified artifact pass. The framework gate verifies Angular partial compilation and tarball contents, not browser hydration of an installed Angular tarball. Browser verification and final 1.0-version artifacts remain open. Logs are retained at /private/tmp/charts-ready-angular-unit-final.log and /private/tmp/charts-ready-angular-packed.log.

The current candidate now builds and validates twelve retained tarballs at 0.18.0, with an integrity manifest in .release-artifacts/manifest.json. These are verification artifacts, not a published release or final 1.0 artifacts. An isolated consumer installs the Charts, scales, and Angular tarballs offline with Angular 22.0.8. Internal package dependencies are explicitly routed to the same candidate tarballs, not the registry or workspace source.

Real browser hydration of that installed consumer passes in Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. Each preserves the server SVG and line nodes, mounts the browser host, updates an accessible label in place, and removes the chart at teardown. No page errors or console warnings/errors occur. The consumer uses Angular's JIT compiler for partial declarations; it does not prove AOT linking or all supported Angular peer versions. Fixture and verifier are retained in /private/tmp/charts-ready-angular-browser.QIU8i1, and artifact build output is /private/tmp/charts-ready-angular-artifacts.log. This audit adds no routine CI job. Combined bundle/performance and final 1.0 gates remain open.

The installed Angular 22.0.8 consumer now also passes AOT compilation and linking. pnpm exec ngc -p tsconfig.json compiles the application with full compilation, strict types, and strict templates. Angular's Babel linker processes thirteen partial-declaration modules for the server and browser builds, including the packed Angular adapter. The browser metafile confirms @angular/compiler is absent. Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5 then pass hydration, SVG/line identity, reactive updates, browser host mounting, and teardown, with no page errors or console warnings/errors. This is AOT evidence, not a JIT fallback. Sources, compiler configuration, lockfile, and verifier remain in /private/tmp/charts-ready-angular-browser.QIU8i1; run the verifier with CHARTS_AUDIT_AOT=1 and optionally CHARTS_AUDIT_BROWSER=firefox or webkit. The toolchain uses Angular compiler-cli 22.0.8, TypeScript 6.0.3, and Babel 7.29.7. One uncached transitive compiler dependency required completing installation with network access. Minimum Angular peer coverage remains open. No production source, package dependency, routine CI job, or size budget changed for this audit.

Compatible follow-up work

The full release-artifact build at 2fcb00a4 passes after the Angular 19 template correction. All twelve 0.18.0 candidate tarballs and their integrity manifest are refreshed in .release-artifacts. Packed exports, portable declarations, runtime consumers, seven framework adapters, unified-package contents, bare React Native Metro, and Expo Metro pass. This closes the stale unified-package verification noted above, not the final 1.0-version artifact, native-device, registry-publication, or comparative size/performance gates.

Minimum-peer Angular 19.0.0 exposed a real template compatibility failure during AOT linking: an alias is not supported on an @else if block. The adapter now aliases structured tooltip content in the primary @if; its string and structured content fields are mutually exclusive. Fresh partial compilation keeps minified module bytes at 12,899 and reduces gzip from 2,979 to 2,978. The installed corrected Angular tarball passes AOT hydration, SVG/line identity, reactive updates, and teardown in Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5 without page errors or console warnings/errors. This consumer uses Angular 19.0.0, TypeScript 5.6.3, Node 24.18.0, and standard Zone.js bootstrap. The retained fixture is /private/tmp/charts-ready-angular-minimum.Rpf3NF. The tooltip test uses reactive options and covers structured-to-text and text-to-structured transitions without replacing its custom body. Final combined package validation and the combined size/performance gates remain open. The corrected tarball also passes strict AOT compilation and linking with Angular 22.0.8 and TypeScript 6.0.3, followed by the same browser checks in all three engines. The full root suite passes 2,202 tests across 301 files after the template and tooltip-test changes. Root TypeScript and whitespace checks pass. These results do not cover every intermediate Angular peer version or replace the final unified-package artifact check.

Pattern resources (#128), crosshair label boxes (#132), JSON/Flint integration (#107/#108), and third-party embedding (#106) can follow in minor releases. They remain outside the 1.0 promise until implemented and documented. Bundle refactoring (#153) is assessed independently. Curved interaction geometry (#42) needs an explicit accuracy and performance decision before its contract is described as stable.

October 3 release verification

The user approved a silent 1.0 release, with the public announcement held for Monday. Changesets selects all twelve fixed public packages for 1.0.0.

Scheduled conformance run 36878815914 failed thirteen comparison cases. Each failure reproduced on the readiness branch. The shadcn reference fixtures used different data, series colors, or background tracks from the upstream examples; the playback overlay also used a theme color instead of the definition's fixed orange. The paint sampler incorrectly selected an invisible fill for line-only radar geometry. Correct those fixtures and sample the visible stroke, without removing paint assertions or changing published runtime code.

All thirteen cases now pass their standard-profile light and dark checks at 320, 640, and 960 pixels, before and after updates. Playback interactions pass across both renderers. Eleven additional reference regressions verify counts and paints through mount, resize, update, and teardown. The full default suite passes 2,231 tests across 301 files. Existing package, adapter, and bundle gates pass. The complete comparison run passes 186 visual cases and all 22 interaction cases. GitHub reproduces only the same two remaining visual mismatches, cases 84 and 120: the sampler compares paints belonging to fully invisible interaction targets. Keep their geometry counts, but exclude zero-opacity fills and strokes from the paint comparison. Both cases and the line-only radar case pass a targeted standard-profile rerun, including their interaction scenarios. The themed reference now shares its example's stylesheet rather than substituting different surface tokens. Final-head CI and registry publication remain pending.

The comparison snapshot is refreshed from the final formatted runtime revision fba40526, with its measured input digest. The controlled ranges use decimal gzip kB, and the catalog coverage is corrected to 188 pairs: 79 Observable Plot, 98 Recharts, and 11 ECharts. No routine CI jobs or bundle ceilings were added.