Skip to content

feat: add source-patched native Oxlint path - #1664

Draft
aidenybai wants to merge 427 commits into
mainfrom
codex/oxc-source-patch
Draft

feat: add source-patched native Oxlint path#1664
aidenybai wants to merge 427 commits into
mainfrom
codex/oxc-source-patch

Conversation

@aidenybai

@aidenybai aidenybai commented Aug 21, 2026

Copy link
Copy Markdown
Member

Current performance fix: 248d574

Commit 248d57435ed2e108014db9ce8c1ac6606b947b44 removes profiled repeated work while preserving canonical diagnostics: bounded declared-workspace discovery; lazy Dayjs mutability analysis; one Next.js file-gating result per context; one resolver per image-ownership project; and render/suppression/depth rejection before expensive hydration import analysis. No checks, traversal limits, or report validation are weakened.

Repeated paired CLI measurements on the optimized release, three measured runs per lane after one excluded warmup:

Repository TypeScript median Native median Speedup
Cal.com 7.141s 6.288s 1.136×
Mantine 6.038s 4.479s 1.348×

Both complete reports match exactly: Cal.com 18 projects / 1,504 diagnostics and Mantine 3 projects / 1,071 diagnostics. The preceding controlled native build took 13.757s and 22.281s respectively. The new committed-head full 44-repository benchmark and 48-repository integrated audit are pending; these two repositories are not an aggregate speedup claim. The preceding full-44 run at e330662bb was still 2.6% slower in summed medians (native 137.582s, TypeScript 134.106s), which prompted this additional profiling and fix.

  • Compile check and optimized release build passed against Oxlint 1.79.0.
  • Exact AST parity: 2,541 baseline diagnostics, plus 1,047 boundary fixtures / 560 diagnostics. The added pair verifies identical import aliases resolve against each consumer's own tsconfig and that a normal consumer still reports the optimizable image.
  • Scan parity: 41 retained rules / 238 fixtures. Project parity: six graph rules plus duplicate JSX across four cases. Scan corpus: 48 repositories / 93 diagnostics / zero differences.
  • Strict canonical required-fire fuzz for the three changed rules: 500 iterations each, 7,556 executed programs, 726 diagnostic-producing programs, zero findings. This does not erase the historical cleanup invariant failure documented below.
  • All local gates passed: test, lint, typecheck, format, JSON-report smoke, native source/registration verification, eight native package tests, and diff check. Independent review and deslop found no blockers.
  • Source SHA-256: 681a45b46bb4ed15fa2bb6bf4bb75eff6d453b8f20e46f8d56738e67cf1b9e09; binding SHA-256: ebcf80e5fbe572e93ab59592bcb2a48b1f3a7437470c91da79756c242151aaa8.
  • Current-head Native Oxlint and CI are pending. The native workflow requires five platform builds, assembly, and eight real tarball installation smokes.

Publication remains paused. Previously prepared experimental tarballs predate these performance fixes and are superseded. Earlier validation below is historical until refreshed. Current local evidence: tmp/native-performance-503a68c4d/resolver-validation.json and regressions-resolver-controlled/results.json.

Add an experimental react-doctor-rust launcher backed by a source-patched Oxlint 1.79.0 binding. The build overlays native rules onto one pinned Oxc commit. The existing TypeScript CLI supplies project discovery, configuration, suppression, and reporting.

Production CLI comparisons exposed missing and extra diagnostics despite complete rule registration. This change restores canonical callback, ref, memo, cleanup, asynchronous control-flow, dependency, and cross-file resolution behavior. Required-native execution rejects missing, incompatible, malformed, and failed analysis instead of silently falling back. Package assembly checks binary hashes and native source fingerprints before accepting artifacts.

Standalone experimental publication preparation

Commit 503a68c4dba6ab7332d213b3874666cbf7085b38 prepares react-doctor-rust@0.9.13-experimental.0 and its five exact-version native platform packages. Explicit --release --version assembly produces public manifests with the experimental tag; ordinary CI assemblies remain private. The launcher bundles the exact built workspace CLI and rule plugin, so it does not require publishing changes to stable react-doctor or oxlint-plugin-react-doctor first. The candidate reports its experimental version.

Assembly records every bundled runtime file hash. Installation smoke verifies those hashes, plugin resolution from the bundled CLI, complete native AST/security/graph success, and all six required-native failure cases. Packing produces six tarballs, checksums, and a reviewable publication plan listing the platform packages before the launcher. The preparation guide documents exact-tarball dry runs and the publication boundary. No action/release workflow, tag, Changeset, merge, or npm publication is part of this change.

  • All required local gates and eight native package unit tests passed.
  • Both private CI and public experimental packages passed real Darwin arm64 clean-install smokes using only the launcher and platform tarballs.
  • All six exact 0.9.13-experimental.0 tarballs passed npm publish --dry-run --ignore-scripts with public access and the experimental tag. This does not establish registry ownership or publishing authentication.
  • Independent review and deslop passed; native detector sources and their fingerprint are unchanged from 56f576b82, so the runtime parity evidence and limits below remain applicable.
  • Packaging-head hosted checks are superseded by the current performance-head checks above. Historical platform evidence below is not a substitute for current-head checks.

Local artifacts and results: tmp/native-release-prep-56f576b82/release-tarballs/release-plan.json, package-validation.json, and release-prep-gates.json. Actual publication still requires fresh approval for the exact six packages/versions and registry-only installation smokes afterward. The channel remains experimental: the last integrated timing was 1.35× faster at the median repository but 38% slower in aggregate, and four corpus reports remain incomplete. It does not support default-engine promotion.

Latest corrections

  • no-pass-data-to-parent distinguishes inline callback parameters from local aliases and ordinary prop member receivers, preserves named-wrapper and debounce alias behavior, follows nested ref calls, and handles callbacks returned by useMemo while ignoring type-only parameter references.
  • js-set-map-lookups reuses the existing binding initializer resolver so string defaults and destructured sources retain their canonical behavior.
  • no-adjust-state-on-prop-change handles destructured state setters, state snapshot refs used as guards, deferred initializer callbacks, and the canonical uppercase callback-binding boundary.
  • Installed-package smoke requires a complete, nonblocking v3 success report with native AST, graph, and security diagnostics. Six failure injections verify missing packages, mismatched versions, missing exports, and malformed security, graph, and duplicate JSX results. Runtime failures must exit 1 and report the expected incomplete public analysis check.

New regression and firing seeds are handwritten. Benchmark source is not copied into the fuzz corpus. Existing fixtures and fuzz invariants remain intact.

Main synchronization and canonical differences

The branch includes main through ff7dd679e8b9939a7dd8f828a530559a275836f7, including owned cleanup paths, cancellation guards, per-call GET helper safety, magic-link mutation exemptions, and compiler opt-out handling.

Canonical TypeScript still intentionally differs from that revision in seven detector files across four changes:

  • Guard memo() with no argument against a crash while retaining its diagnostic (3ced1c98d).
  • Bound hydration parameter resolution across execution contexts to stop argument cycles (82a4d2645).
  • Support Windows filename separators in four React Router rules (b404f030e).
  • Limit synchronous arithmetic/update warnings in rerender-functional-setstate to another same-setter call that reads state, ignoring nested function calls (72fd97b2a).

Dedicated regression tests cover all four groups. Shared canonical AST/provenance helper implementations are unchanged from main; shared rule metadata marks five already disabled rules as retired. Core native dispatch, normalization, caching, analysis, and failure gating also differ. This is not a claim that the TypeScript engine is identical to main apart from crash guards.

Coverage and verified local checks

Coverage remains 906 canonical rules: all 864 AST rules and 41 of 42 scan rules are native-backed, representing 905/906 canonical behaviors and 55/56 Security rules, with 1,734 generated Oxc implementations. The sole deliberate exclusion is local-rpc-native-bridge-risk. postmessage-origin-risk retains its canonical WebSocket, Worker, MessagePort, BroadcastChannel, and EventSource suppressions.

Final optimized release validation at 56f576b82c7b03d173350ee95827c58527a80b6c uses native source fingerprint 5bccdfec928a551e219b962eba0eb0202601b2cb73479fd1bc34706f2f223c95 and binding SHA-256 17890718768463e43173b0b98d8d8134bc521d36873ad90d69a4e811f1e8c25f.

Check Verified result
Compile check and optimized release build Passed against pinned Oxlint 1.79.0
Release AST parity 2,541 baseline diagnostics plus 1,028 boundary fixtures / 549 diagnostics; exact comparison passed
Release scan parity 41 rules / 238 fixtures; exact comparison passed
Release project parity Six graph rules and duplicate JSX across four cases passed
Release scan corpus 48 repositories / 93 diagnostics / zero differences
Latest handwritten reductions 120 focused cases passed
Latest whole-file replay 11 files / six diagnostics; exact comparison passed
Installed local Darwin arm64 package Four real tarballs passed the complete success report and all six failure injections
Required local gates Tests, lint, typecheck, formatting, JSON report smoke, native verification, and diff checks passed
Latest strict required-fire fuzz Three corrected rules, 500 iterations each; 7,477 executed programs / 556 diagnostic-producing programs / zero findings

The final installed smoke used private 0.0.0 native packages and the real CLI/plugin packages. Its artifacts are in tmp/native-smoke-hardening/local-darwin-Y9DEey; the release validation manifest is tmp/native-full-parity-2f4568744/final-release-validation.json. This validates the local Darwin package; it does not substitute for all-target assembly or the eight CI installation smokes.

Retained failures and evidence limits

The final production CLI run at 56f576b82 completed all 48 repositories: 44 repositories / 197 projects matched exactly, with zero diagnostic differences among complete reports; four repositories returned incomplete reports in both engines. The five previously differing repositories now all pass, including Supabase's 13 projects and 4,346 full diagnostic objects. Source, binding, and built CLI fingerprints remained unchanged throughout the run. Runtime coverage passed: all 41 retained scan rules were requested, 366 native AST spawns and 145 native duplicate JSX calls were observed, and a separate graph-enabled CLI scenario fired all six graph rules exactly through the native project worker.

The four completeness failures are retained: Leemons has an invalid settings.react.version; Reactide exceeds the one-million-character source limit; Twenty exceeds the 5,000-file and source-length limits; Next.js exceeds those limits and contains an invalid UTF-8 fixture. The incomplete reports contain identical diagnostic objects and multiplicities too (7, 91, 2,318, and 3,279 respectively), but remain failed completeness checks. The report validator and analysis limits were not weakened. Evidence: tmp/native-full-parity-56f576b82/integrated-2026-09-06T02-54-22.375Z/summary.json and incomplete-diagnostic-audit.json.

Historical confirmed totals remain 181,665 integrated diagnostics and 522,000 strict required-fire fuzz mutations. The final-head corpus run has four incomplete reports and does not replace the historical integrated total. Later focused checks and changed corpus selections do not establish updated performance claims.

The canonical cleanup invariant at seed 1000234, iteration 231 remains unfixed, with its failure artifact and reproducer preserved. Extracting stored-observer cleanup into a local helper changes both engines from zero diagnostics to one. The canonical cleanup detector is unchanged from main at ff7dd679e. A green fuzz run after corpus additions can select different mutations and does not erase this failure or weaken the invariant.

Independent Daytona comparison between main at ff7dd679e and final head 56f576b82 matched 128,776 diagnostic identities per lane across 43 validated, unredacted repositories: zero additions and zero removals, with matching repository pins, evaluator/configuration contracts, and project coverage. This is a separate TypeScript main-versus-PR check; local same-revision TypeScript-versus-native evidence is reported above.

The complete remote 48-repository verdict remains unavailable. Baseline Supabase Studio hit the canonical hydration argument-cycle stack overflow; the candidate produced a valid Supabase report, but its saved strings were sanitized and cannot support exact comparison. Cal.com, Outline, and Twenty were sanitized in both lanes and are excluded too. Next.js failed in both lanes; candidate attempts retained two invalid-UTF-8 validator rejections and two command timeouts. Baseline and candidate had zero malformed rows, but both lanes remain incomplete under the unchanged validator. The two reported task-owned sandbox cleanup timeouts and the run's snapshot were subsequently confirmed absent. Evidence: tmp/parity-independent-recovery/independent-valid-comparison-56f576b82.json and independent-final-attribution-56f576b82.json.

Detector-validation results at 56f576b

Item Verified result
Detector-validation commit 56f576b82c7b03d173350ee95827c58527a80b6c
Optimized release binding and metadata PASS — source and binary hashes above
Release-binding parity and installed smoke rerun PASS — exact results and artifact paths above
Final committed-head production CLI corpus 44 exact / 4 incomplete — full results and failure attribution above; no complete 48-repository parity claim
Independent final-head Daytona candidate 43 exact / 5 excluded pairs — 128,776 diagnostics per lane, zero additions/removals; no complete 48-repository verdict
Hosted CI at detector-validation commit Ordinary CI PASS, all seven jobs; Native Oxlint PASS, all five platform builds, parity checks, and artifact uploads
Five-target assembly and eight installation smokes PASS at 56f576b82: package assembly plus Linux x64/arm64 on Node 20.19 and 22.18, Darwin x64/arm64 and Windows x64 on Node 22.18, including both Linux glibc 2.28 installation environments

This remains a draft PR. This experimental native and internal validation work adds no Changeset. No merge, publication, release tag, or package release is performed.

@pkg-pr-new

pkg-pr-new Bot commented Aug 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-react-doctor@1664
npm i https://pkg.pr.new/oxlint-plugin-react-doctor@1664
npm i https://pkg.pr.new/react-doctor@1664

commit: 248d574

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 248d574.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Interactive terminal E2E

Terminal Control verified the built CLI at 248d574 in a real PTY:

  • selected a project interactively and observed Scanning... before the three-second Git delay completed
  • waited for the clean result and exercised the compact report
  • opened copy context and the GitHub Actions confirmation, then cancelled safely

Download the edited MP4 and PNG evidence

@aidenybai
aidenybai force-pushed the codex/oxc-source-patch branch 2 times, most recently from fc576d5 to 1e12d5f Compare August 21, 2026 06:39
@aidenybai
aidenybai marked this pull request as ready for review September 2, 2026 09:13
@aidenybai
aidenybai marked this pull request as draft September 3, 2026 00:52
@aidenybai
aidenybai marked this pull request as ready for review September 3, 2026 06:44
@aidenybai

Copy link
Copy Markdown
Member Author

bugbot run

@cursor

cursor Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings.

@aidenybai
aidenybai marked this pull request as draft September 3, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant