[GH-ISSUE #1237] fix(electron): later dynamic overrides retain a stale preload association #438

Closed
opened 2026-10-15 18:25:03 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 9, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1237

Summary

Static Electron application analysis retains an earlier literal BrowserWindow preload after a later unknown duplicate property, spread or computed key can replace it. The result reports a resolved window-to-preload relationship even though the effective preload is unknown. The observed property syntax remains available, but the separate effective-path association points to the overwritten candidate.

Steps to reproduce

Create this two-file fixture in a disposable directory and run the published baseline listed under Runtime or environment:

fixture_dir=$(mktemp -d)
cat > "$fixture_dir/main.js" <<'JS'
new BrowserWindow({webPreferences:{preload:"./first.js",preload:runtimePath}});
JS
cat > "$fixture_dir/first.js" <<'JS'
globalThis.fixtureFirst = 1;
JS
npx -y rea-agents@6.1.0 analyze-javascript-application "$fixture_dir" --format json

The unresolved identifier is intentional. This is inert source analysis, and the effective value of the final property must remain unknown. Inspect the BrowserWindow observation's preload_path and the loads edge whose evidence extractor operation is associate-browser-window-preload. For the main build, use a checkout built with npm ci and npm run build:cached, and replace the npx runner with node scripts/rea.mjs while retaining the command arguments. Both CLI builds reproduced this two-file reduction.

Executed variants replaced the second preload property with ...runtimeOptions or [runtimeKey]:runtimeValue; both retained the same stale association. Executed ordering controls put the dynamic property or spread before final explicit preload:"./first.js"; those correctly resolve first.js. A two-literal duplicate control with final preload:"./last.js" and an inventoried last.js correctly resolves the final path.

The MCP equivalent is analyze_javascript_application with input_path set to the absolute fixture directory. The dynamic duplicate case was also reproduced through a real stdio MCP session on the main build.

Expected behavior

Keep observed property syntax and source ranges, but report the effective BrowserWindow preload as unknown when a later unresolved property can override the earlier literal. Do not attach that BrowserWindow to the overwritten path as a resolved preload relationship. A final explicit literal should still resolve when it follows an unknown earlier property or spread.

The existing documentation says, "Dynamic option objects, bridge keys, API objects, and IPC channel expressions remain unknown and make coverage partial." Existing Electron option tests already apply that effective-value rule when a later unknown computed key can replace the outer BrowserWindow options property.

Actual behavior

Both tested CLI builds exit 0. The BrowserWindow observation reports:

{"preload_path":"./first.js","preload_resolution_context":"module-specifier"}

It preserves both the earlier literal and the later dynamic property in web_preferences. It also emits a loads edge whose evidence extractor operation is associate-browser-window-preload, with these properties:

{"declared_path":"./first.js","resolution_context":"module-specifier","resolved_path":"first.js","resolution_status":"resolved","limitations":[]}

The later spread and computed-key variants give the same stale result. Coverage is partial, but the effective-path relationship still says resolved and has no override limitation. The main MCP response succeeds with isError: false and retains the same earlier preload_path.

A harmless plain-object comparison was executed with runtimePath='./last.js', runtimeOptions={preload:'./last.js'}, runtimeKey='preload' and runtimeValue='./last.js'. Each corresponding later-override object evaluates to { "preload": "./last.js" }; the reversed-order controls evaluate to { "preload": "./first.js" }. This comparison establishes property ordering without launching Electron or executing the analyzed fixture. No Electron runtime, security or isolation consequence is claimed.

Evidence

  • Expected source: docs/javascript-artifact-reconstruction.md:194-197 requires dynamic options to remain unknown; src/domain/javascript/electronStaticAnalysisOptions.test.ts:27-46 requires a later unknown computed key to suppress an earlier effective value at the outer options boundary.
  • Failure source: Executed public CLI analysis of the inline fixture on both tested builds, including the two-file reduction, returned the quoted BrowserWindow observation and resolved preload edge. A real main-build stdio MCP call retained the same earlier path.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Source inspection shows collectWebPreferences in src/domain/javascript/electronStaticAnalysisBrowser.ts:109-146 retaining its earlier preload value after later spreads, computed fields or dynamic duplicate values. src/application/javascript/ElectronBoundaryGraphWindows.ts:108-145 projects that retained value into the window's preload relationship. This is source-derived reasoning consistent with the observations, rather than a prescribed repair.

Open and closed issue searches covered preload spreads, overrides and duplicate web preferences. No exact duplicate was found. The related runtime-semantic tracing discussion does not describe this static effective-path result.

Runtime or environment

Published package rea-agents@6.1.0; current default-branch build at f0da05f67fff1411cf2f7a48a752ee7b348c71ff. Runtime: Node.js v26.10.0, macOS 27.0.1, arm64. Targets were authored local JavaScript directory fixtures. The release and main CLI paths were tested; stdio MCP was tested on main. No Electron process or deep binary-analysis provider was used.

Restoration check

A later unresolved duplicate preload, spread or computed key must leave the effective BrowserWindow preload unknown and must not create a resolved window-to-preload association from the earlier literal. Preserve observed property syntax and source locations. The ordering controls with a final explicit literal and the final-literal duplicate control must retain their correct resolved association. Generic property candidate observations are distinct from the effective BrowserWindow association and need not be discarded wholesale.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The bounded fixtures associate a BrowserWindow with an overwritten preload role and file, which can mislead static reconstruction. Analysis remains available; Electron runtime incidence and downstream analyst use were not measured.
  • Workaround status: available
  • Workaround basis: The retained exact syntax and source locations were verified to expose the later duplicate, spread and computed writes. Inspect those writes and disregard the earlier effective preload association when a later unresolved value can replace it. This checks the uncertainty without executing the target, although the returned association remains incorrect.
Originally created by @coygeek on GitHub (Oct 9, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1237 ## Summary Static Electron application analysis retains an earlier literal BrowserWindow preload after a later unknown duplicate property, spread or computed key can replace it. The result reports a resolved window-to-preload relationship even though the effective preload is unknown. The observed property syntax remains available, but the separate effective-path association points to the overwritten candidate. ## Steps to reproduce Create this two-file fixture in a disposable directory and run the published baseline listed under Runtime or environment: ```sh fixture_dir=$(mktemp -d) cat > "$fixture_dir/main.js" <<'JS' new BrowserWindow({webPreferences:{preload:"./first.js",preload:runtimePath}}); JS cat > "$fixture_dir/first.js" <<'JS' globalThis.fixtureFirst = 1; JS npx -y rea-agents@6.1.0 analyze-javascript-application "$fixture_dir" --format json ``` The unresolved identifier is intentional. This is inert source analysis, and the effective value of the final property must remain unknown. Inspect the BrowserWindow observation's `preload_path` and the `loads` edge whose evidence extractor operation is `associate-browser-window-preload`. For the main build, use a checkout built with `npm ci` and `npm run build:cached`, and replace the npx runner with `node scripts/rea.mjs` while retaining the command arguments. Both CLI builds reproduced this two-file reduction. Executed variants replaced the second preload property with `...runtimeOptions` or `[runtimeKey]:runtimeValue`; both retained the same stale association. Executed ordering controls put the dynamic property or spread before final explicit `preload:"./first.js"`; those correctly resolve `first.js`. A two-literal duplicate control with final `preload:"./last.js"` and an inventoried `last.js` correctly resolves the final path. The MCP equivalent is `analyze_javascript_application` with `input_path` set to the absolute fixture directory. The dynamic duplicate case was also reproduced through a real stdio MCP session on the main build. ## Expected behavior Keep observed property syntax and source ranges, but report the effective BrowserWindow preload as unknown when a later unresolved property can override the earlier literal. Do not attach that BrowserWindow to the overwritten path as a resolved preload relationship. A final explicit literal should still resolve when it follows an unknown earlier property or spread. The existing documentation says, "Dynamic option objects, bridge keys, API objects, and IPC channel expressions remain unknown and make coverage partial." Existing Electron option tests already apply that effective-value rule when a later unknown computed key can replace the outer BrowserWindow options property. ## Actual behavior Both tested CLI builds exit 0. The BrowserWindow observation reports: ```json {"preload_path":"./first.js","preload_resolution_context":"module-specifier"} ``` It preserves both the earlier literal and the later dynamic property in `web_preferences`. It also emits a `loads` edge whose evidence extractor operation is `associate-browser-window-preload`, with these properties: ```json {"declared_path":"./first.js","resolution_context":"module-specifier","resolved_path":"first.js","resolution_status":"resolved","limitations":[]} ``` The later spread and computed-key variants give the same stale result. Coverage is partial, but the effective-path relationship still says resolved and has no override limitation. The main MCP response succeeds with `isError: false` and retains the same earlier `preload_path`. A harmless plain-object comparison was executed with `runtimePath='./last.js'`, `runtimeOptions={preload:'./last.js'}`, `runtimeKey='preload'` and `runtimeValue='./last.js'`. Each corresponding later-override object evaluates to `{ "preload": "./last.js" }`; the reversed-order controls evaluate to `{ "preload": "./first.js" }`. This comparison establishes property ordering without launching Electron or executing the analyzed fixture. No Electron runtime, security or isolation consequence is claimed. ## Evidence - Expected source: `docs/javascript-artifact-reconstruction.md:194-197` requires dynamic options to remain unknown; `src/domain/javascript/electronStaticAnalysisOptions.test.ts:27-46` requires a later unknown computed key to suppress an earlier effective value at the outer options boundary. - Failure source: Executed public CLI analysis of the inline fixture on both tested builds, including the two-file reduction, returned the quoted BrowserWindow observation and resolved preload edge. A real main-build stdio MCP call retained the same earlier path. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Source inspection shows `collectWebPreferences` in `src/domain/javascript/electronStaticAnalysisBrowser.ts:109-146` retaining its earlier preload value after later spreads, computed fields or dynamic duplicate values. `src/application/javascript/ElectronBoundaryGraphWindows.ts:108-145` projects that retained value into the window's preload relationship. This is source-derived reasoning consistent with the observations, rather than a prescribed repair. Open and closed issue searches covered preload spreads, overrides and duplicate web preferences. No exact duplicate was found. The related runtime-semantic tracing discussion does not describe this static effective-path result. ## Runtime or environment Published package `rea-agents@6.1.0`; current default-branch build at `f0da05f67fff1411cf2f7a48a752ee7b348c71ff`. Runtime: Node.js `v26.10.0`, macOS `27.0.1`, arm64. Targets were authored local JavaScript directory fixtures. The release and main CLI paths were tested; stdio MCP was tested on main. No Electron process or deep binary-analysis provider was used. ## Restoration check A later unresolved duplicate preload, spread or computed key must leave the effective BrowserWindow preload unknown and must not create a resolved window-to-preload association from the earlier literal. Preserve observed property syntax and source locations. The ordering controls with a final explicit literal and the final-literal duplicate control must retain their correct resolved association. Generic property candidate observations are distinct from the effective BrowserWindow association and need not be discarded wholesale. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The bounded fixtures associate a BrowserWindow with an overwritten preload role and file, which can mislead static reconstruction. Analysis remains available; Electron runtime incidence and downstream analyst use were not measured. - Workaround status: available - Workaround basis: The retained exact syntax and source locations were verified to expose the later duplicate, spread and computed writes. Inspect those writes and disregard the earlier effective preload association when a later unresolved value can replace it. This checks the uncertainty without executing the target, although the returned association remains incorrect.
bsakaguchi 2026-10-15 18:25:03 +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#438
No description provided.