[GH-ISSUE #2670] fix(javascript): Electron entrypoint paths select undeclared HTML siblings #971

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

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

Summary

Static directory analysis associates an extensionless Electron preload and utility-process entrypoint with a sibling HTML file that the source did not name. With ./entry declared and only entry.html present, the graph marks both associations resolved and reports one resolved utility entrypoint. This changes the caller-selected runtime filename and can direct reconstruction to the wrong asset.

Steps to reproduce

In a source checkout with its runtime already built, create this two-file fixture. The source is analyzed as inert text and must not be executed.

fixture_dir="$(pwd)/electron-entry-fixture"
mkdir "$fixture_dir"
cat > "$fixture_dir/main.cjs" <<'JS'
const { BrowserWindow, utilityProcess } = require("electron");
new BrowserWindow({ webPreferences: { preload: "./entry" } });
utilityProcess.fork("./entry");
JS
cat > "$fixture_dir/entry.html" <<'HTML'
<!doctype html><title>fixture</title>
HTML
node scripts/rea.mjs analyze-javascript-application "$fixture_dir" --json

The fixture was reduced to these two files and executed through the source reconstruction service and the shared analyzeJavaScriptApplication service used by the CLI. The equivalent CLI command above is provided for replay and was not executed during this verification. Inspect the electron-preload observation whose mechanism is BrowserWindow:webPreferences.preload, the graph edge whose extractor operation is resolve-utility-process-entrypoint, and normalized_result.summary.resolved_utility_entrypoints.

The same discrepancy was separately reproduced with path.join(__dirname, "preload") and path.join(__dirname, "worker") and only preload.html and worker.html present. The directory-analysis input accepts both declaration forms.

Expected behavior

Electron runtime entrypoint paths retain the runtime filename selected by the caller. When the selected entry file is absent, preserve ./entry and return a non-resolved association with a lookup reason, rather than associating it with entry.html. The utility summary should not count this declaration as resolved. Exact declarations naming existing script files should still resolve.

This is a filename-identity requirement. The report does not require proving that a declared script executes or validating all possible script formats.

Actual behavior

The shared application service returned success, and the returned graph passed parseJavaScriptApplicationGraph. Its BrowserWindow preload role contained:

{"declared_path":"./entry","resolution_context":"module-specifier","resolved_path":"entry.html","resolution_status":"resolved","limitations":[],"mechanism":"BrowserWindow:webPreferences.preload"}

The utility entrypoint mapping contained:

{"declared_path":"./entry","resolution_context":"module-specifier","resolved_path":"entry.html","resolution_status":"resolved"}

The resolved utility count was 1, although a direct file-inventory check confirmed that entry was absent. There were zero source parse failures. The relationship evidence correctly retained state: "inferred" and the limitation Static syntax does not prove that this relationship executes at runtime. The empty array above is the resolution property, not an absence of all evidence limitations.

The separate filesystem-expression fixture also selected its HTML siblings and counted the utility entrypoint. A fixture without either target file returned a null, not-found preload, no utility mapping, and count 0. Explicit .js declarations with their script files present resolved to the exact scripts and returned count 1.

Evidence

  • Expected source: docs/javascript-artifact-reconstruction.md:210-213 says that literal Electron preload, renderer, and utility-process runtime paths retain the runtime filename selected by the caller. Its public directory workflow is documented at lines 13-53.
  • Failure source: Independently executed two-file directory fixture through reconstructJavaScriptArtifact and analyzeJavaScriptApplication, with the returned graph independently parsed. Relevant code locators are src/application/javascript/ElectronBoundaryGraphWindows.ts:130-139 and 268-274, JavaScriptArtifactPathResolution.ts:921-949, ElectronBoundaryAnalysis.ts:155-164, and the CLI adapter at src/cli/javascriptApplicationAnalysis.ts:15-26.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The fixture outputs and controls were directly observed through source services. The compiled CLI, released package, and Electron runtime were not run.

Related closed reports cover CommonJS extension probing and selected package exports targets. Those reports concern separate loader and package-target contracts. This report concerns Electron runtime path declarations.

Related: #2561 concerns literal file-URL conversion before asset lookup, and #2521 concerns computed preference names. Neither covers extensionless Electron runtime filename selection.

Restoration check

With the two-file fixture unchanged, the preload must retain its declaration and an unresolved path with an actionable lookup reason. The utility must have no resolved association to entry.html, and the resolved utility count must be 0. Verify the same result for dirname-derived filesystem expressions. Keep the passing absent-target control and explicit .js control, including exact resolved paths and utility count 1 for existing declared scripts. Preserve the distinction between inferred static relationships and observed execution.

Runtime or environment

Source revision a2d8b94dd50dab8d966239dd63ab84718aa8b4b4, tested with Node 24.18.0 and npm 11.16.0. The focused source test ran twice successfully; the second run added the two-file reduction and shared application service check. No released-runtime comparison was performed.

Current upstream source recheck at 3ae826ceba6f25b08bce50bcb51001209bc16b57 found the same filename-selection defect still present. This was a source-only recheck, not a new runtime run. The supplied latest registry release, rea-agents@6.4.0, was not executed.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Owned directory fixtures show resolved static associations to a different filename and an incorrect resolved utility count. This is a bounded reconstruction defect; analysis remains available, and broader production incidence was not measured.
  • Workaround status: available
  • Workaround basis: Independently compare the retained declaration against the inventoried exact filename before following the association. This check was verified on the reduced fixture: entry is absent and only entry.html exists. It detects the unsupported association without modifying or executing the analyzed application; it does not repair the generated graph.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2670 ## Summary Static directory analysis associates an extensionless Electron preload and utility-process entrypoint with a sibling HTML file that the source did not name. With `./entry` declared and only `entry.html` present, the graph marks both associations resolved and reports one resolved utility entrypoint. This changes the caller-selected runtime filename and can direct reconstruction to the wrong asset. ## Steps to reproduce In a source checkout with its runtime already built, create this two-file fixture. The source is analyzed as inert text and must not be executed. ```sh fixture_dir="$(pwd)/electron-entry-fixture" mkdir "$fixture_dir" cat > "$fixture_dir/main.cjs" <<'JS' const { BrowserWindow, utilityProcess } = require("electron"); new BrowserWindow({ webPreferences: { preload: "./entry" } }); utilityProcess.fork("./entry"); JS cat > "$fixture_dir/entry.html" <<'HTML' <!doctype html><title>fixture</title> HTML node scripts/rea.mjs analyze-javascript-application "$fixture_dir" --json ``` The fixture was reduced to these two files and executed through the source reconstruction service and the shared `analyzeJavaScriptApplication` service used by the CLI. The equivalent CLI command above is provided for replay and was not executed during this verification. Inspect the `electron-preload` observation whose mechanism is `BrowserWindow:webPreferences.preload`, the graph edge whose extractor operation is `resolve-utility-process-entrypoint`, and `normalized_result.summary.resolved_utility_entrypoints`. The same discrepancy was separately reproduced with `path.join(__dirname, "preload")` and `path.join(__dirname, "worker")` and only `preload.html` and `worker.html` present. The directory-analysis input accepts both declaration forms. ## Expected behavior Electron runtime entrypoint paths retain the runtime filename selected by the caller. When the selected `entry` file is absent, preserve `./entry` and return a non-resolved association with a lookup reason, rather than associating it with `entry.html`. The utility summary should not count this declaration as resolved. Exact declarations naming existing script files should still resolve. This is a filename-identity requirement. The report does not require proving that a declared script executes or validating all possible script formats. ## Actual behavior The shared application service returned success, and the returned graph passed `parseJavaScriptApplicationGraph`. Its BrowserWindow preload role contained: ```json {"declared_path":"./entry","resolution_context":"module-specifier","resolved_path":"entry.html","resolution_status":"resolved","limitations":[],"mechanism":"BrowserWindow:webPreferences.preload"} ``` The utility entrypoint mapping contained: ```json {"declared_path":"./entry","resolution_context":"module-specifier","resolved_path":"entry.html","resolution_status":"resolved"} ``` The resolved utility count was `1`, although a direct file-inventory check confirmed that `entry` was absent. There were zero source parse failures. The relationship evidence correctly retained `state: "inferred"` and the limitation `Static syntax does not prove that this relationship executes at runtime.` The empty array above is the resolution property, not an absence of all evidence limitations. The separate filesystem-expression fixture also selected its HTML siblings and counted the utility entrypoint. A fixture without either target file returned a null, `not-found` preload, no utility mapping, and count `0`. Explicit `.js` declarations with their script files present resolved to the exact scripts and returned count `1`. ## Evidence - Expected source: `docs/javascript-artifact-reconstruction.md:210-213` says that literal Electron preload, renderer, and utility-process runtime paths retain the runtime filename selected by the caller. Its public directory workflow is documented at lines 13-53. - Failure source: Independently executed two-file directory fixture through `reconstructJavaScriptArtifact` and `analyzeJavaScriptApplication`, with the returned graph independently parsed. Relevant code locators are `src/application/javascript/ElectronBoundaryGraphWindows.ts:130-139` and `268-274`, `JavaScriptArtifactPathResolution.ts:921-949`, `ElectronBoundaryAnalysis.ts:155-164`, and the CLI adapter at `src/cli/javascriptApplicationAnalysis.ts:15-26`. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The fixture outputs and controls were directly observed through source services. The compiled CLI, released package, and Electron runtime were not run. Related closed reports cover [CommonJS extension probing](https://github.com/morluto/rea/issues/2022) and [selected package exports targets](https://github.com/morluto/rea/issues/1174). Those reports concern separate loader and package-target contracts. This report concerns Electron runtime path declarations. Related: #2561 concerns literal file-URL conversion before asset lookup, and #2521 concerns computed preference names. Neither covers extensionless Electron runtime filename selection. ## Restoration check With the two-file fixture unchanged, the preload must retain its declaration and an unresolved path with an actionable lookup reason. The utility must have no resolved association to `entry.html`, and the resolved utility count must be `0`. Verify the same result for dirname-derived filesystem expressions. Keep the passing absent-target control and explicit `.js` control, including exact resolved paths and utility count `1` for existing declared scripts. Preserve the distinction between inferred static relationships and observed execution. ## Runtime or environment Source revision `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`, tested with Node 24.18.0 and npm 11.16.0. The focused source test ran twice successfully; the second run added the two-file reduction and shared application service check. No released-runtime comparison was performed. Current upstream source recheck at `3ae826ceba6f25b08bce50bcb51001209bc16b57` found the same filename-selection defect still present. This was a source-only recheck, not a new runtime run. The supplied latest registry release, `rea-agents@6.4.0`, was not executed. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Owned directory fixtures show resolved static associations to a different filename and an incorrect resolved utility count. This is a bounded reconstruction defect; analysis remains available, and broader production incidence was not measured. - Workaround status: available - Workaround basis: Independently compare the retained declaration against the inventoried exact filename before following the association. This check was verified on the reduced fixture: `entry` is absent and only `entry.html` exists. It detects the unsupported association without modifying or executing the analyzed application; it does not repair the generated graph.
bsakaguchi 2026-10-15 18:30:00 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@aakash-env commented on GitHub (Oct 13, 2026):

@coygeek @baron @monomyth kindly assign this issue to me

<!-- gh-comment-id:6141400963 --> @aakash-env commented on GitHub (Oct 13, 2026): @coygeek @baron @monomyth kindly assign this issue to me
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#971
No description provided.