[GH-ISSUE #6543] [Bug] Local loadFile methods create resolved Electron renderer nodes #3934

Closed
opened 2026-10-31 00:45:22 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

A locally defined object method cache.loadFile that only returns its argument creates an electron-renderer node for data.json. The graph adds loads and maps_to edges, labels the target resolved, and assigns the renderer inference high confidence while reporting complete graph coverage. The fixture contains no Electron import or renderer creation. This was observed by executing the source analysis and graph-construction functions on the published release and main; no CLI/MCP execution is claimed.

Reproduction

The executed probe imported analyzeJavaScriptArtifactFiles and buildJavaScriptArtifactGraph from the selected checkout, passed retained file records with real SHA-256 digests and UTF-8 byte lengths, and supplied a minimal in-memory directory inventory snapshot. It exercised the production parser, analyzer, and validated application graph builder. It did not exercise filesystem acquisition, the compiled worker, CLI, or MCP transport, and it never evaluated the fixture JavaScript. The fixture's container hash was SHA-256 of the text fixture; there were no unavailable files, nested containers, or integrity contradictions.

The following equivalent focused probe shows the complete input construction. Its literal reduced presentation was not separately executed; the executed probe contained the same case alongside other independent fixtures. Save it as probe.mts outside the checkout, select the checkout as the working directory, and run node --import tsx /path/to/probe.mts "$PWD" after installing the checkout's locked dependencies.

import { createHash } from "node:crypto";
import { pathToFileURL } from "node:url";
const repo = process.argv[2];
const load = (p: string) => import(pathToFileURL(`${repo}/src/${p}.ts`).href);
const { analyzeJavaScriptArtifactFiles } = await load("application/javascript/JavaScriptArtifactAnalysis");
const { buildJavaScriptArtifactGraph } = await load("application/javascript/JavaScriptArtifactGraphBuilder");
const hash = (s: string) => createHash("sha256").update(s).digest("hex");
const rootHash = hash("fixture");
const entries = { "main.js": 'const cache = { loadFile(name) { return name; } }; cache.loadFile("./data.json");', "data.json": '{"value":1}' };
const files = Object.entries(entries).map(([path, text]) => ({
  path, container_sha256: rootHash, sha256: hash(text), bytes: Buffer.byteLength(text),
  inventory_artifact_id: `art_${hash(text)}`, kind: path.endsWith(".js") ? "javascript" : "json",
  unpacked: false, text: { included: true, value: text },
}));
const fileSet = { files, unavailable_relevant_files: [], containers: [], text_bytes_read: files.reduce((n, f) => n + f.bytes, 0), invalid_utf8_files: 0 };
const snapshot = {
  manifest: { root_artifact_id: `art_${rootHash}`, root_sha256: rootHash, root_format: "directory", manifest_id: `agm_${rootHash}`, graph_sha256: rootHash },
  nodes: [{ artifact_id: `art_${rootHash}`, sha256: rootHash, size: 1 }], occurrences: [], integrity_contradictions: [],
};
const graph = buildJavaScriptArtifactGraph(snapshot, fileSet, analyzeJavaScriptArtifactFiles(fileSet));
console.log(JSON.stringify({ nodes: graph.nodes.filter((n: any) => n.kind === "electron-renderer"), edges: graph.edges.filter((e: any) => ["loads", "maps_to"].includes(e.relation)), coverage: graph.coverage }));

Both selected checkouts produced the result described below in the initial probe pass. This is a focused production-function reproduction, not an end-to-end public-interface reproduction.

Expected behavior

A proven local method that only returns its argument should not establish an Electron renderer or renderer loading relationship. Preserve the ordinary call syntax, or explicitly retain uncertainty if receiver identity cannot be established. The source itself supplies the receiver's complete local definition, so the generic limitation that static syntax does not prove runtime execution does not explain this false API identity.

Impact and scope

The demonstrated fixture produces a false resolved application architecture relationship on both tested revisions. This can misdirect an analyst from an ordinary local method to a non-renderer JSON file. Only the exact loadFile local receiver case was executed; similar loadURL handling is visible in source but was not probed.

REA version

Published rea-agents-6.7.0, source revision 27dc42d10249f0410904a75c0997842eb03b931c; main source revision 1635eadfcc49bbb80178838ab74667c2981de383. Both were probed with their locked dependencies.

Runtime and platform

Node.js v26.12.1; Linux x86_64. No browser, Electron target, Hopper, Ghidra, or external analysis provider was started.

Target and artifact context

An inert two-file JavaScript directory represented by retained file records: main.js and data.json. No ASAR or native binary was involved.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

The executed probe returned this renderer observation on both revisions, with high-confidence static-relationship evidence:

{"declared_path":"./data.json","resolution_context":"filesystem-expression","resolved_path":"data.json","resolution_status":"resolved","limitations":[],"mechanism":"call:cache.loadFile"}

The graph contained loads and maps_to relationships and coverage.status was complete. Main additionally retained runtime_path_base: "application-root"; the incorrect renderer classification remained.

The published producer and main producer classify an exact .loadFile suffix without consulting receiver provenance. The published graph projection creates an Electron role and a loads edge from this result; main retains the same projection. Both graph-builder entry points share the same construction steps used by static artifact reconstruction.

Additional context

Searches covered the open issue inventory and open/closed queries for loadFile renderer, loadURL unrelated, loadFile receiver, and renderer local loadFile. Related issue #2678 explicitly concerns different final callee names such as uploadFile and states that receiver-type inference is outside that report. This case uses the exact recognized method spelling on a proven local receiver, so correcting suffix boundaries alone does not address it.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Valid ordinary source produces a false application graph fact with complete coverage on both the latest published release and main. The demonstrated impact is bounded to the affected classification, with no data mutation or execution.
  • Workaround status: unverified
  • Workaround basis: An analyst can recognize this reduced fixture by reading its local receiver definition, but no general workflow that filters only false nodes while retaining genuine findings was tested.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6543 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior A locally defined object method `cache.loadFile` that only returns its argument creates an `electron-renderer` node for `data.json`. The graph adds `loads` and `maps_to` edges, labels the target resolved, and assigns the renderer inference high confidence while reporting complete graph coverage. The fixture contains no Electron import or renderer creation. This was observed by executing the source analysis and graph-construction functions on the published release and main; no CLI/MCP execution is claimed. ### Reproduction The executed probe imported `analyzeJavaScriptArtifactFiles` and `buildJavaScriptArtifactGraph` from the selected checkout, passed retained file records with real SHA-256 digests and UTF-8 byte lengths, and supplied a minimal in-memory directory inventory snapshot. It exercised the production parser, analyzer, and validated application graph builder. It did not exercise filesystem acquisition, the compiled worker, CLI, or MCP transport, and it never evaluated the fixture JavaScript. The fixture's container hash was SHA-256 of the text `fixture`; there were no unavailable files, nested containers, or integrity contradictions. The following equivalent focused probe shows the complete input construction. Its literal reduced presentation was not separately executed; the executed probe contained the same case alongside other independent fixtures. Save it as `probe.mts` outside the checkout, select the checkout as the working directory, and run `node --import tsx /path/to/probe.mts "$PWD"` after installing the checkout's locked dependencies. ```typescript import { createHash } from "node:crypto"; import { pathToFileURL } from "node:url"; const repo = process.argv[2]; const load = (p: string) => import(pathToFileURL(`${repo}/src/${p}.ts`).href); const { analyzeJavaScriptArtifactFiles } = await load("application/javascript/JavaScriptArtifactAnalysis"); const { buildJavaScriptArtifactGraph } = await load("application/javascript/JavaScriptArtifactGraphBuilder"); const hash = (s: string) => createHash("sha256").update(s).digest("hex"); const rootHash = hash("fixture"); const entries = { "main.js": 'const cache = { loadFile(name) { return name; } }; cache.loadFile("./data.json");', "data.json": '{"value":1}' }; const files = Object.entries(entries).map(([path, text]) => ({ path, container_sha256: rootHash, sha256: hash(text), bytes: Buffer.byteLength(text), inventory_artifact_id: `art_${hash(text)}`, kind: path.endsWith(".js") ? "javascript" : "json", unpacked: false, text: { included: true, value: text }, })); const fileSet = { files, unavailable_relevant_files: [], containers: [], text_bytes_read: files.reduce((n, f) => n + f.bytes, 0), invalid_utf8_files: 0 }; const snapshot = { manifest: { root_artifact_id: `art_${rootHash}`, root_sha256: rootHash, root_format: "directory", manifest_id: `agm_${rootHash}`, graph_sha256: rootHash }, nodes: [{ artifact_id: `art_${rootHash}`, sha256: rootHash, size: 1 }], occurrences: [], integrity_contradictions: [], }; const graph = buildJavaScriptArtifactGraph(snapshot, fileSet, analyzeJavaScriptArtifactFiles(fileSet)); console.log(JSON.stringify({ nodes: graph.nodes.filter((n: any) => n.kind === "electron-renderer"), edges: graph.edges.filter((e: any) => ["loads", "maps_to"].includes(e.relation)), coverage: graph.coverage })); ``` Both selected checkouts produced the result described below in the initial probe pass. This is a focused production-function reproduction, not an end-to-end public-interface reproduction. ### Expected behavior A proven local method that only returns its argument should not establish an Electron renderer or renderer loading relationship. Preserve the ordinary call syntax, or explicitly retain uncertainty if receiver identity cannot be established. The source itself supplies the receiver's complete local definition, so the generic limitation that static syntax does not prove runtime execution does not explain this false API identity. ### Impact and scope The demonstrated fixture produces a false resolved application architecture relationship on both tested revisions. This can misdirect an analyst from an ordinary local method to a non-renderer JSON file. Only the exact `loadFile` local receiver case was executed; similar `loadURL` handling is visible in source but was not probed. ### REA version Published `rea-agents-6.7.0`, source revision `27dc42d10249f0410904a75c0997842eb03b931c`; main source revision `1635eadfcc49bbb80178838ab74667c2981de383`. Both were probed with their locked dependencies. ### Runtime and platform Node.js v26.12.1; Linux x86_64. No browser, Electron target, Hopper, Ghidra, or external analysis provider was started. ### Target and artifact context An inert two-file JavaScript directory represented by retained file records: `main.js` and `data.json`. No ASAR or native binary was involved. ### Interface Other ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence The executed probe returned this renderer observation on both revisions, with high-confidence static-relationship evidence: ```json {"declared_path":"./data.json","resolution_context":"filesystem-expression","resolved_path":"data.json","resolution_status":"resolved","limitations":[],"mechanism":"call:cache.loadFile"} ``` The graph contained `loads` and `maps_to` relationships and `coverage.status` was `complete`. Main additionally retained `runtime_path_base: "application-root"`; the incorrect renderer classification remained. The [published producer](https://github.com/morluto/rea/blob/27dc42d10249f0410904a75c0997842eb03b931c/src/domain/javascript/javascriptStaticAnalysisCalls.ts#L134) and [main producer](https://github.com/morluto/rea/blob/1635eadfcc49bbb80178838ab74667c2981de383/src/domain/javascript/javascriptStaticAnalysisCalls.ts#L140) classify an exact `.loadFile` suffix without consulting receiver provenance. The [published graph projection](https://github.com/morluto/rea/blob/27dc42d10249f0410904a75c0997842eb03b931c/src/application/javascript/JavaScriptArtifactGraphFindings.ts#L344) creates an Electron role and a `loads` edge from this result; [main retains the same projection](https://github.com/morluto/rea/blob/1635eadfcc49bbb80178838ab74667c2981de383/src/application/javascript/JavaScriptArtifactGraphFindings.ts#L480). Both graph-builder entry points share the same construction steps used by static artifact reconstruction. ### Additional context Searches covered the open issue inventory and open/closed queries for `loadFile renderer`, `loadURL unrelated`, `loadFile receiver`, and `renderer local loadFile`. Related issue [#2678](https://github.com/morluto/rea/issues/2678) explicitly concerns different final callee names such as `uploadFile` and states that receiver-type inference is outside that report. This case uses the exact recognized method spelling on a proven local receiver, so correcting suffix boundaries alone does not address it. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Valid ordinary source produces a false application graph fact with complete coverage on both the latest published release and main. The demonstrated impact is bounded to the affected classification, with no data mutation or execution. - Workaround status: unverified - Workaround basis: An analyst can recognize this reduced fixture by reading its local receiver definition, but no general workflow that filters only false nodes while retaining genuine findings was tested.
Author
Owner

@Jackzigen commented on GitHub (Oct 24, 2026):

Verified with the probe from the issue report.

  • At the reported revision 1635eadf the probe still produces the phantom electron-renderer node and its maps_to edge for the local cache.loadFile(...) call.
  • Re-running the same probe at current main produces neither.
  • The fix lands at 5f13ddd75 (fix(javascript): require API identity for static application roles): the probe reproduces at its parent f91b7f800 and is clean from 5f13ddd75 onward.

Looks resolved — this can be closed.

<!-- gh-comment-id:6380427756 --> @Jackzigen commented on GitHub (Oct 24, 2026): Verified with the probe from the issue report. - At the reported revision `1635eadf` the probe still produces the phantom `electron-renderer` node and its `maps_to` edge for the local `cache.loadFile(...)` call. - Re-running the same probe at current `main` produces neither. - The fix lands at `5f13ddd75` (*fix(javascript): require API identity for static application roles*): the probe reproduces at its parent `f91b7f800` and is clean from `5f13ddd75` onward. Looks resolved — this can be closed.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Checked the reported fix on main at d87e73f2db.

The exact local cache.loadFile trigger is blocked by a renderer API-identity predicate before a renderer role is emitted. The unit regression supplies the same local object and asserts no role; public CLI/stdio-MCP regression supplies data.json and rejects that path among renderer/preload observations while retaining a real BrowserWindow load. This supports closure for the reported false renderer.

Implementation: javascriptStaticAnalysisCalls.ts, javascriptStaticApiIdentity.test.ts.

The relevant regression checks in javascriptStaticApiIdentity.test.ts, javascriptStaticApiIdentity.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380713963 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. The exact local cache.loadFile trigger is blocked by a renderer API-identity predicate before a renderer role is emitted. The unit regression supplies the same local object and asserts no role; public CLI/stdio-MCP regression supplies data.json and rejects that path among renderer/preload observations while retaining a real BrowserWindow load. This supports closure for the reported false renderer. Implementation: [javascriptStaticAnalysisCalls.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/javascript/javascriptStaticAnalysisCalls.ts#L151), [javascriptStaticApiIdentity.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/javascript/javascriptStaticApiIdentity.test.ts#L123). The relevant regression checks in [javascriptStaticApiIdentity.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/javascript/javascriptStaticApiIdentity.test.ts), [javascriptStaticApiIdentity.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/acceptance/applications/javascriptStaticApiIdentity.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3934
No description provided.