[GH-ISSUE #1842] [Bug] Electron interop helper names can attribute unrelated constructors to Electron #620

Closed
opened 2026-10-15 18:26:41 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @N0zoM1z0 on GitHub (Oct 11, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1842

Before submitting

  • I searched open/closed issues and PRs for this symptom.
  • The reproduction is generated inert source with no credentials or private targets.

Area

Evidence, artifacts, or reconstruction

Observed behavior

After #1827, a locally declared function named __toESM that explicitly returns an unrelated FakeWindow object is treated as preserving the Electron module. The application graph reports one Electron BrowserWindow despite this constructor not belonging to Electron.

Reproduction

Create an application directory with package.json containing {"main":"main.cjs"} and this main.cjs:

const __toESM = () => ({BrowserWindow:FakeWindow});
let electron = require("electron");
electron = __toESM(electron, 1);
new electron.BrowserWindow({});
throw new Error("this source must stay inert");

Run node scripts/rea.mjs analyze-javascript-application <directory> --format json.

Expected behavior

Preserve Electron origin only for a structurally proven namespace conversion or identity helper. An emitted name alone must not override an explicit unrelated return value; unproven helper results should remain unresolved.

Impact and scope

False Electron boundary observations and source provenance can be recorded for custom, altered, async, or ambiguous helper functions. Legitimate released Rolldown conversions must continue to resolve. This is a false positive introduced by #1827, distinct from #1802's original missing-window report.

REA version

6.4.0 source, 0b4ce83618bb800627264ae6221e2e35140417b5 (main includes #1827, merge 6ac5c36503492d3b6da4fcf2a5dee87aff60fc8c).

Runtime and platform

Linux x64, Node.js 24.18.0, npm 11.16.0; no Electron or deep-analysis provider executed.

Target and artifact context

Generated CommonJS application source. Static analysis only.

Interface

CLI

Earliest failure stage

Artifact or evidence registration (static Electron identity classification).

Relevant output or evidence

Public CLI exited 0, summary.browser_windows: 1, statistics.parse_failures: 0 on the source above. The helper's return is explicitly {BrowserWindow:FakeWindow}.

Typed outcome or recovery expected

An unresolved helper result, with static identity limitations retained, instead of a proven Electron boundary finding.

Analysis or suspected cause

Source-derived: semanticNamespaceInteropOperand checks emitted names and a stable program-scope function definition but does not verify the returned module identity or helper body.

Additional context

I am preparing a focused follow-up with real CLI/stdio MCP controls, modified-helper negatives, and the exact public T3 nightly main producer source (without executing Electron).

Originally created by @N0zoM1z0 on GitHub (Oct 11, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1842 ### Before submitting - [x] I searched open/closed issues and PRs for this symptom. - [x] The reproduction is generated inert source with no credentials or private targets. ### Area Evidence, artifacts, or reconstruction ### Observed behavior After #1827, a locally declared function named `__toESM` that explicitly returns an unrelated `FakeWindow` object is treated as preserving the Electron module. The application graph reports one Electron BrowserWindow despite this constructor not belonging to Electron. ### Reproduction Create an application directory with `package.json` containing `{"main":"main.cjs"}` and this `main.cjs`: ```js const __toESM = () => ({BrowserWindow:FakeWindow}); let electron = require("electron"); electron = __toESM(electron, 1); new electron.BrowserWindow({}); throw new Error("this source must stay inert"); ``` Run `node scripts/rea.mjs analyze-javascript-application <directory> --format json`. ### Expected behavior Preserve Electron origin only for a structurally proven namespace conversion or identity helper. An emitted name alone must not override an explicit unrelated return value; unproven helper results should remain unresolved. ### Impact and scope False Electron boundary observations and source provenance can be recorded for custom, altered, async, or ambiguous helper functions. Legitimate released Rolldown conversions must continue to resolve. This is a false positive introduced by #1827, distinct from #1802's original missing-window report. ### REA version 6.4.0 source, `0b4ce83618bb800627264ae6221e2e35140417b5` (main includes #1827, merge `6ac5c36503492d3b6da4fcf2a5dee87aff60fc8c`). ### Runtime and platform Linux x64, Node.js 24.18.0, npm 11.16.0; no Electron or deep-analysis provider executed. ### Target and artifact context Generated CommonJS application source. Static analysis only. ### Interface CLI ### Earliest failure stage Artifact or evidence registration (static Electron identity classification). ### Relevant output or evidence Public CLI exited 0, `summary.browser_windows: 1`, `statistics.parse_failures: 0` on the source above. The helper's return is explicitly `{BrowserWindow:FakeWindow}`. ### Typed outcome or recovery expected An unresolved helper result, with static identity limitations retained, instead of a proven Electron boundary finding. ### Analysis or suspected cause Source-derived: `semanticNamespaceInteropOperand` checks emitted names and a stable program-scope function definition but does not verify the returned module identity or helper body. ### Additional context I am preparing a focused follow-up with real CLI/stdio MCP controls, modified-helper negatives, and the exact public T3 nightly main producer source (without executing Electron).
bsakaguchi 2026-10-15 18:26:41 +00:00
Author
Owner

@morluto commented on GitHub (Oct 11, 2026):

Root-cause audit follow-up against main fb94d9dde0ccda83ae520ac6fb22b1d283562cf3:

The false-positive boundary is still semanticNamespaceInteropOperand in src/domain/javascript/javascriptSemanticRequireOrigin.ts: a familiar helper name and one program-scope function definition are treated as proof that the result exposes the operand's members. Neither condition establishes the helper's behavior. This must be resolved before Electron findings and their provenance are produced.

The existing returned-value/reference utilities can follow direct returns and member projections, but they cannot establish the released Rolldown helper's dynamic own-key enumeration, live getter forwarding, and prototype behavior. Removing recognition without replacing that proof would regress the released-bundle positive case.

The required invariant is a bounded semantic proof of the conversion's member identity, with these controls:

  • Preserve the released Rolldown conversion and equivalent renamed helper/parameter bindings.
  • Preserve a stable synchronous helper that directly returns its operand.
  • Keep fake, async/generator, conditional/fallback, changed-getter, mismatched-source/key, reassigned, and overwritten-intrinsic cases unresolved.
  • Preserve original source anchors and unknown preload expressions through both CLI and MCP.
  • Keep captured intrinsic identity and visible writes under a clear semantic owner; helper spelling must not select behavior.

Related fix: #1857 already replaces name-only trust with structural proof and reports substantial source, CLI/MCP, and released-producer validation. The additional concern from this cleanup audit is maintainability: its roughly 500-line interop checker plus intrinsic/mutator tracking deserves explicit review as a semantic ownership boundary, so subsequent fixes do not grow a second emitter-specific interpreter or duplicate existing return, binding, traversal, and mutation rules. Prefer reusing those owners where it removes observed duplication while retaining the negative controls above.

This audit did not establish an additional correctness failure in #1857 and did not independently rerun its reported real-producer validation. The Electron slice was left unchanged in the cleanup worktree; this remains the tracked issue and proposed fix, rather than a new duplicate bug.

<!-- gh-comment-id:6110667320 --> @morluto commented on GitHub (Oct 11, 2026): Root-cause audit follow-up against main `fb94d9dde0ccda83ae520ac6fb22b1d283562cf3`: The false-positive boundary is still `semanticNamespaceInteropOperand` in `src/domain/javascript/javascriptSemanticRequireOrigin.ts`: a familiar helper name and one program-scope function definition are treated as proof that the result exposes the operand's members. Neither condition establishes the helper's behavior. This must be resolved before Electron findings and their provenance are produced. The existing returned-value/reference utilities can follow direct returns and member projections, but they cannot establish the released Rolldown helper's dynamic own-key enumeration, live getter forwarding, and prototype behavior. Removing recognition without replacing that proof would regress the released-bundle positive case. The required invariant is a bounded semantic proof of the conversion's member identity, with these controls: - Preserve the released Rolldown conversion and equivalent renamed helper/parameter bindings. - Preserve a stable synchronous helper that directly returns its operand. - Keep fake, async/generator, conditional/fallback, changed-getter, mismatched-source/key, reassigned, and overwritten-intrinsic cases unresolved. - Preserve original source anchors and unknown preload expressions through both CLI and MCP. - Keep captured intrinsic identity and visible writes under a clear semantic owner; helper spelling must not select behavior. Related fix: #1857 already replaces name-only trust with structural proof and reports substantial source, CLI/MCP, and released-producer validation. The additional concern from this cleanup audit is maintainability: its roughly 500-line interop checker plus intrinsic/mutator tracking deserves explicit review as a semantic ownership boundary, so subsequent fixes do not grow a second emitter-specific interpreter or duplicate existing return, binding, traversal, and mutation rules. Prefer reusing those owners where it removes observed duplication while retaining the negative controls above. This audit did not establish an additional correctness failure in #1857 and did not independently rerun its reported real-producer validation. The Electron slice was left unchanged in the cleanup worktree; this remains the tracked issue and proposed fix, rather than a new duplicate bug.
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#620
No description provided.