Skip to content

fix(deps): keep react and react-dom on one update so neither ships alone - #362

Merged
lamemustafa merged 1 commit into
masterfrom
tapish-codex/react-version-parity
Sep 15, 2026
Merged

lamemustafa merged 1 commit into
masterfrom
tapish-codex/react-version-parity

Conversation

@lamemustafa

Copy link
Copy Markdown
Owner

Summary

Group react with react-dom (and their types) in Dependabot so a React update cannot arrive as two PRs that are each unmergeable without the other. Adds a lockfile-level regression test so the grouping does not depend on being remembered.

Supersedes #361, which bumped react 19.2.8 → 19.3.0 while leaving react-dom at 19.2.8 and failed 25 suites.

Root Cause / Decision Record

.github/dependabot.yml grouped by risk and deliberately left the runtime dependencies ungrouped, so each update reaching a taxpayer's browser would arrive as its own PR with its own disposition. That reasoning is right for @wxt-dev/module-react. It does not hold for react and react-dom, because React enforces exact-version equality between them at runtime:

Error: Incompatible React versions: The "react" and "react-dom" packages must have the exact same version.

So ungrouping them does not produce two independently reviewable updates. It produces one PR that fails every component suite and a second that cannot be merged before it. This is not a one-off: it recurs on every React release, and #361 is the instance that surfaced it.

Smallest safe fix: put the four React packages in their own react group. This is not a relaxation of the risk rule — the group is still separate from dev-tooling, still arrives as its own runtime PR, and is still dispositioned on its own. What changes is only that the two packages React requires to move together do move together.

The rule is then removed from the category of things that must be remembered. tests/repo/react-runtime-version-parity.test.ts asserts the resolved react and react-dom versions in pnpm-lock.yaml are equal, so a mismatch fails the suite however it arrives — a grouped update gone wrong, a manual edit, or a future config change that ungroups them again.

The test asserts against the lockfile rather than the declared ranges in package.json, following the reasoning already recorded in tests/repo/node-runtime-types-alignment.test.ts: the lockfile states what is installed, cannot be expressed as a range, and cannot be commented out. Two mutually compatible ^ ranges can still resolve apart, so checking ranges would pass while broken.

Scope

  • Runtime: none. No src/** change and no packaged-output change.
  • Tests: one new repo-level test.
  • Docs/governance: .github/dependabot.yml comments record why the exception exists.
  • Explicitly out of scope: performing the React 19.3.0 upgrade itself. That arrives as a fresh grouped Dependabot PR once this lands.

Pack Workflow Preflight

  • pnpm workflow:preflight was run before editing/push, or the skip reason is documented.
  • This PR was opened from a Pack branch, not master.
  • I checked latest master Pack AGENTS guidance or recorded the stale-guidance warning.
  • PR body keeps the required Pack privacy/review/verification checklist visible.

Sanchika Adoption Gate

Not applicable: no Sanchika adoption.

  • If this PR consumes @sanchika/* packages or copied Sanchika guidance, I
    read sanchika/docs/adoption-pack.md in the coordinated parent worktree.
  • If this PR consumes Sanchika, it links ComplyEaze and Axal completion evidence
    and records the Sanchika commit or copied guidance used.
  • This PR does not import ../sanchika, sanchika/packages/*/src, or parent
    source paths.

Privacy And Data-Flow Impact

  • No new browser permissions.
  • No new host permissions.
  • No new network calls.
  • No analytics, telemetry, ads, or session replay.
  • No credential, OTP, CAPTCHA, cookie, token, GST file, or taxpayer-data capture.
  • Public copy and privacy declarations are updated if behaviour changed — behaviour did not change.

Sensitive Surface Review

  • Current tab / portal target binding is preserved or intentionally changed — untouched.
  • Download completion remains evidence-backed and fail-closed — untouched.
  • Ambiguous side-effect delivery cannot be reported as confirmed success — untouched.
  • Service-worker durability impact is understood and documented — none.
  • Real taxpayer data, local paths, raw URLs/referrers, and portal HTML are absent from the diff.

Chrome Web Store Impact

  • This PR does not expand beyond the existing Chrome Web Store V0 listing unless every gate in docs/PUBLICATION_READINESS.md is checked.
  • Full fiscal year remains source-only and excluded from the next packaged Store build until its evidence gates are recorded.
  • Store copy, README status, Privacy QA, and reviewer instructions were reviewed if user-facing behavior changed — no user-facing change.
  • CI ZIP creation, provenance, and protected publishing are treated as release evidence, not manual store-submission sign-off.
  • PR title uses Conventional Commits so Release Please can bump Pack after merge.

Verification

Run locally against this branch:

  • pnpm exec prettier --check . — "All matched files use Prettier code style!"
  • pnpm exec eslint . --max-warnings 0 — clean
  • pnpm exec tsc --noEmit — clean
  • pnpm exec vitest run

Vitest, verbatim:

 Test Files  177 passed (177)
      Tests  3313 passed (3313)
   Duration  299.93s (tests 95%, import 4%, transform 1%)
    Isolate  177 workers spawned · ~99ms startup each (spawn + environment, per file)
             at least ~17.36s faster with isolate: false — reuses workers across files instead of one per file

The new guard was driven to failure before being trusted. With pnpm-lock.yaml edited to the exact #361 mismatch (react 19.2.8, react-dom 19.3.0), the test fails:

× resolves react and react-dom to the same version
AssertionError: expected '19.3.0' to be '19.2.8' // Object.is equality

The lockfile was restored immediately; git diff pnpm-lock.yaml is empty and no lockfile change is part of this PR.

Not run, and not claimed: pnpm audit --audit-level high, wxt build/zip, package and ZIP verification, provenance and Store scripts. No packaged output changes here — the diff is one YAML config and one repo test.

  • pnpm review:gate -- --strict-head-review --wait-head-review-ms 180000 before merge/readiness claim; a missing Codex review blocks readiness:

Left unchecked. Codex review capacity is exhausted until roughly 2026-09-19, so no current-head review can arrive. CI's own gate invocation passes --allow-missing-head-review, so the required check does not depend on it.

Artifact Evidence

  • CI run: see this PR's checks.
  • ZIP artifact: none — not a release PR.
  • ZIP SHA-256: not applicable.
  • Clean source/tag or head SHA: this PR's head.

PR Review Follow-Up

  • GitHub Actions completed.
  • Autogenerated Codex/bot review comments inspected after checks completed for the latest head SHA — none, and none can arrive while Codex capacity is exhausted.
  • Inline review threads are resolved, outdated, or answered with evidence — there are none.
  • No commits were pushed after the last required human/bot review without re-review.
  • Any follow-up PRs or issues are listed here instead of being left implicit.
Thread/comment Disposition Commit or evidence
None — no review threads exist on this PR accepted Review-thread query returns zero threads for this head
#361 (the broken split bump) superseded by this PR Closed in favour of this config fix; the React 19.3.0 upgrade returns as a grouped PR once this lands

Screenshots

None. No user-facing surface changed.

`.github/dependabot.yml` deliberately left the runtime dependencies ungrouped so
each arrives as its own reviewable PR. React makes that impossible for two of
them: it refuses to run when `react` and `react-dom` disagree -- "Incompatible
React versions: the react and react-dom packages must have the exact same
version". Separate PRs therefore do not produce two independently reviewable
updates; they produce one broken PR and one that cannot merge before it. #361
bumped react 19.2.8 without react-dom and failed 25 suites for exactly that
reason, and this recurs on every React release.

Grouping the two preserves what the ungrouped rule was actually for: this is
still a runtime PR of its own, separate from dev-tooling, reviewed and
dispositioned on its own. `@wxt-dev/module-react` stays ungrouped; it carries no
such constraint.

Adds `tests/repo/react-runtime-version-parity.test.ts` so the grouping does not
rely on being remembered, following `node-runtime-types-alignment.test.ts`: one
assertion against the resolved versions in `pnpm-lock.yaml`, which state what is
installed and cannot be written as a range or commented out. Confirmed to fail
when the lockfile is edited to the exact #361 mismatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lamemustafa
lamemustafa marked this pull request as ready for review September 15, 2026 14:14
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@lamemustafa
lamemustafa merged commit 2d96a45 into master Sep 15, 2026
9 checks passed
@lamemustafa
lamemustafa deleted the tapish-codex/react-version-parity branch September 15, 2026 14:18
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