[PR #7255] [CLOSED] fix(javascript): prove Webpack interop from loader aliases #7750

Closed
opened 2026-11-03 13:40:07 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7255
Author: @BeqaKs
Created: 10/26/2026
Status: ❌ Closed

Base: main ← Head: fix/javascript-webpack-interop-alias-bound


📝 Commits (4)

  • 888b7ff fix(javascript): prove Webpack interop from loader aliases
  • e786d10 fix(javascript): select loader aliases at write time
  • 2ba6e03 chore: merge upstream/main to retrigger CI
  • b441e58 chore: merge upstream/main into fix/javascript-webpack-interop-alias-bound

📊 Changes

2 files changed (+101 additions, -3 deletions)

View changed files

📝 src/domain/javascript/electronBundledRequireIdentity.test.ts (+52 -1)
📝 src/domain/javascript/javascriptBundledRequireOrigin.ts (+49 -2)

📄 Description

Summary

  • Prove Webpack n.n interop by expanding loader-owned bindings from the loader set, instead of walking every identity-write root toward the loader.
  • Synthetic unrelated long alias chains no longer trip alias-selections and withhold Electron windows/IPC handlers; the reported Bitwarden case remains unresolved.
  • Greptile P1 follow-up: owned bindings are candidates only; write sites confirm with semanticBindingAtRead, and unused shallow loader aliases no longer invalidate the getter proof.

Related to #7253

Problem and expected behavior

canonicalWebpackInteropBindings treated an alias-selection bound hit as “this write may own the loader.” On a large Webpack Electron main bundle that flooded loader mutation candidates, so the canonical getter proof failed and browser_windows / many IPC handlers disappeared versus 6.7.0.

A follow-up ownership set then kept aliases after reassignment (var copy=n; copy={}; copy.n=1) and failed the proof when more than 512 unused var aN=n declarations existed.

Change and scope

JavaScript semantic analysis only. No provider, MCP contract, or setup change. Maintainer scope decision not applicable.

  • Expand empty-projection aliases from the loader as a candidate set (no proof failure from shallow alias volume alone).
  • At each identity-write root, require the binding to be a candidate and still reach the loader via semanticBindingAtRead (bounded per write).

Contract and boundary impact

  • Generated metadata: none
  • CLI/MCP: same tools; richer Electron facts when the loader is unmodified

Expected effects:

  • Existing public surface preserves caller-selected inputs and returns Evidence with provenance
  • Target execution, injection, mutation, or protection recovery

Evidence and regression coverage

  • Module test: 600-step unrelated alias chain keeps one BrowserWindow, IPC handler, and no alias-selections limit
  • Module test: var copy=n;copy={};copy.n=1 with an n.n consumer still keeps BrowserWindow
  • Module test: 513 unused var aN=n aliases still keep BrowserWindow with no alias-selections limit
  • Existing getter-replacement cases (including stable loader aliases / Reflect through alias) still withhold Electron
  • Real Bitwarden 2026.10.0 ASAR rerun: the reported counts remain unchanged; see the follow-up below.

Reported real-artifact follow-up

The reported Bitwarden 2026.10.0 asset was rerun on macOS arm64 using Node 24.22.1 and the source CLI, selecting main.js and preload.js with NODE_OPTIONS=--max-old-space-size=5120. The 122,097,388-byte DEB matched SHA-256 fcabfc7da3c327e2625b105e951cee4e60703bb8e256f0aac9cc9bc83ec7063f; the extracted ASAR was 71,317,476 bytes. On both current-main 21b192706 and this PR head b441e5818, the completed call returned 0 windows, 0 explicit web preferences, 112 IPC operations, 32 main handlers, and partial graph coverage with alias-selections. This PR therefore does not yet restore the specific reported result; #7253 remains open.

An instrumented PR-head run traced the first bootstrap integrity refusal to the dynamic __webpack_require__.m[moduleId] = moreModules[moduleId] in the chunk installer at main.js:139231, before the interop getter proof changed here. The program also has a __webpack_require__.e(368) call; the selected-source analysis did not include the ASAR's 368.js. Treating that write as absent would overstate loader integrity. Other alias-limit owners also fired; the instrumentation does not prove each owner's contribution to every missing fact.

One fresh-process sample per revision with warmed OS file caches took 34.65 s on main and 34.67 s on the PR, with 44.18 s and 43.66 s of child CPU respectively. Sampled peak process-family RSS at 0.5-second intervals was 1,856.7 MiB and 1,752.2 MiB; short peaks may be missed. CPU includes sampling subprocess overhead. Each invocation used a 1 GiB JavaScript worker heap in addition to the selected parent heap; complete JSON output was about 70 MB. These single samples do not establish a performance difference. Warm-session comparisons, tokenizer/catalog costs, real runtime registration, and Linux-host behavior were not measured.

Validation performed

  • npm run test:local -- src/domain/javascript/electronBundledRequireIdentity.test.ts — 73 passed on the exact PR head (macOS arm64, Node 24.22.1).
  • npm run check:fast

Author readiness

Human owner: @BeqaKs

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7255 **Author:** [@BeqaKs](https://github.com/BeqaKs) **Created:** 10/26/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/javascript-webpack-interop-alias-bound` --- ### 📝 Commits (4) - [`888b7ff`](https://github.com/morluto/rea/commit/888b7ffe1e61824bcbe6913264cd343675a0ccaf) fix(javascript): prove Webpack interop from loader aliases - [`e786d10`](https://github.com/morluto/rea/commit/e786d10dbe6204a3a6c71a56407be37f228473b5) fix(javascript): select loader aliases at write time - [`2ba6e03`](https://github.com/morluto/rea/commit/2ba6e032d968eb77273f8d8ec8c18b66ad6c489a) chore: merge upstream/main to retrigger CI - [`b441e58`](https://github.com/morluto/rea/commit/b441e5818db940e686913071876ca1609bc9c67a) chore: merge upstream/main into fix/javascript-webpack-interop-alias-bound ### 📊 Changes **2 files changed** (+101 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascript/electronBundledRequireIdentity.test.ts` (+52 -1) 📝 `src/domain/javascript/javascriptBundledRequireOrigin.ts` (+49 -2) </details> ### 📄 Description ## Summary - Prove Webpack `n.n` interop by expanding loader-owned bindings from the loader set, instead of walking every identity-write root toward the loader. - Synthetic unrelated long alias chains no longer trip `alias-selections` and withhold Electron windows/IPC handlers; the reported Bitwarden case remains unresolved. - Greptile P1 follow-up: owned bindings are candidates only; write sites confirm with `semanticBindingAtRead`, and unused shallow loader aliases no longer invalidate the getter proof. Related to #7253 ## Problem and expected behavior `canonicalWebpackInteropBindings` treated an alias-selection bound hit as “this write may own the loader.” On a large Webpack Electron main bundle that flooded loader mutation candidates, so the canonical getter proof failed and `browser_windows` / many IPC handlers disappeared versus 6.7.0. A follow-up ownership set then kept aliases after reassignment (`var copy=n; copy={}; copy.n=1`) and failed the proof when more than 512 unused `var aN=n` declarations existed. ## Change and scope JavaScript semantic analysis only. No provider, MCP contract, or setup change. Maintainer scope decision not applicable. - Expand empty-projection aliases from the loader as a candidate set (no proof failure from shallow alias volume alone). - At each identity-write root, require the binding to be a candidate and still reach the loader via `semanticBindingAtRead` (bounded per write). ## Contract and boundary impact - Generated metadata: none - CLI/MCP: same tools; richer Electron facts when the loader is unmodified Expected effects: - [x] Existing public surface preserves caller-selected inputs and returns Evidence with provenance - [ ] Target execution, injection, mutation, or protection recovery ## Evidence and regression coverage - Module test: 600-step unrelated alias chain keeps one `BrowserWindow`, IPC handler, and no `alias-selections` limit - Module test: `var copy=n;copy={};copy.n=1` with an `n.n` consumer still keeps `BrowserWindow` - Module test: 513 unused `var aN=n` aliases still keep `BrowserWindow` with no `alias-selections` limit - Existing getter-replacement cases (including stable loader aliases / Reflect through alias) still withhold Electron - Real Bitwarden 2026.10.0 ASAR rerun: the reported counts remain unchanged; see the follow-up below. ### Reported real-artifact follow-up The reported Bitwarden 2026.10.0 asset was rerun on macOS arm64 using Node 24.22.1 and the source CLI, selecting `main.js` and `preload.js` with `NODE_OPTIONS=--max-old-space-size=5120`. The 122,097,388-byte DEB matched SHA-256 `fcabfc7da3c327e2625b105e951cee4e60703bb8e256f0aac9cc9bc83ec7063f`; the extracted ASAR was 71,317,476 bytes. On both current-main `21b192706` and this PR head `b441e5818`, the completed call returned 0 windows, 0 explicit web preferences, 112 IPC operations, 32 main handlers, and partial graph coverage with `alias-selections`. This PR therefore does not yet restore the specific reported result; #7253 remains open. An instrumented PR-head run traced the first bootstrap integrity refusal to the dynamic `__webpack_require__.m[moduleId] = moreModules[moduleId]` in the chunk installer at `main.js:139231`, before the interop getter proof changed here. The program also has a `__webpack_require__.e(368)` call; the selected-source analysis did not include the ASAR's `368.js`. Treating that write as absent would overstate loader integrity. Other alias-limit owners also fired; the instrumentation does not prove each owner's contribution to every missing fact. One fresh-process sample per revision with warmed OS file caches took 34.65 s on main and 34.67 s on the PR, with 44.18 s and 43.66 s of child CPU respectively. Sampled peak process-family RSS at 0.5-second intervals was 1,856.7 MiB and 1,752.2 MiB; short peaks may be missed. CPU includes sampling subprocess overhead. Each invocation used a 1 GiB JavaScript worker heap in addition to the selected parent heap; complete JSON output was about 70 MB. These single samples do not establish a performance difference. Warm-session comparisons, tokenizer/catalog costs, real runtime registration, and Linux-host behavior were not measured. ## Validation performed - `npm run test:local -- src/domain/javascript/electronBundledRequireIdentity.test.ts` — 73 passed on the exact PR head (macOS arm64, Node 24.22.1). - `npm run check:fast` ## Author readiness Human owner: @BeqaKs - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:40:07 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7750
No description provided.