[GH-ISSUE #2678] fix(javascript): unrelated callee names produce renderer and service-worker nodes #978

Closed
opened 2026-10-15 18:30:02 +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/2678

Summary

Analyzing an ordinary JavaScript directory adds Electron renderer and service-worker entities for unrelated local functions whose names merely share an API suffix. Locally defined no-op uploadFile and downloadURL functions produce electron-renderer nodes, and a no-op myserviceWorker.register method produces a service-worker node. These false classifications survive application graph validation and appear in the returned analysis Evidence.

Steps to reproduce

Use a checkout at the source baseline under Runtime or environment with its pinned dependencies installed, and build it once with npm run build:cached. The shared CLI boundary starts the compiled analysis worker, and npm run test:local does not build it for a source test. Create these three independent directory fixtures from the repository root. The fixture contents below were each tested through the production shared CLI boundary.

mkdir -p callee-repro/upload callee-repro/download callee-repro/worker
for case in upload download worker; do
  printf '%s\n' '{"main":"main.cjs"}' > "callee-repro/$case/package.json"
done
cat > callee-repro/upload/main.cjs <<'JS'
function uploadFile() {}
uploadFile("upload.html");
JS
cat > callee-repro/download/main.cjs <<'JS'
function downloadURL() {}
downloadURL("https://example.invalid/page");
JS
cat > callee-repro/worker/main.cjs <<'JS'
const myserviceWorker = { register() {} };
myserviceWorker.register("./sw.js");
JS

Save this reproduction test as src/application/javascript/calleeRecognitionRepro.test.ts. It asserts the observed false classifications and prints their declared inputs. It invokes the production boundary used by the CLI, rather than executing any fixture source.

import { resolve } from "node:path";
import { expect, it } from "vitest";
import { runCliJavaScriptApplicationAnalysis } from "../../cli/javascriptApplicationAnalysis.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";

it.each([
  ["upload", "electron-renderer"],
  ["download", "electron-renderer"],
  ["worker", "service-worker"],
])("shows the false classification for %s", async (name, kind) => {
  const evidence = await runCliJavaScriptApplicationAnalysis({
    input_path: resolve("callee-repro", name),
  });
  expect(evidence).toHaveProperty("operation", "analyze_javascript_application");
  const result = javascriptApplicationAnalysisResultSchema.parse(
    (evidence as Record<string, unknown>).normalized_result,
  );
  const nodes = result.graph.nodes.filter(
    node => node.kind === "electron-renderer" || node.kind === "service-worker",
  );
  expect(nodes.map(node => node.kind)).toEqual([kind]);
  console.log(JSON.stringify({
    fixture: name,
    nodes: nodes.map(node => ({
      kind: node.kind,
      observations: node.observations.map(observation => ({
        label: observation.label,
        properties: observation.properties,
      })),
    })),
  }));
}, 20000);
npm run test:local -- src/application/javascript/calleeRecognitionRepro.test.ts

Local verification on the original source baseline ran an equivalent focused test through a serialized source-test launcher, with these same three inputs, boundary calls and graph assertions. The public reproduction above changes only fixture placement and test presentation; its literal command and filename were not rerun. Seven checks passed: three isolated syntax cases, one control check, and three shared CLI-boundary directory cases. No packaged standalone CLI or stdio MCP transport was exercised.

Expected behavior

The static application graph should preserve these ordinary local calls without classifying them as Electron renderer loading or service-worker registration. The fixture functions and method do nothing, and their names are different from the recognized APIs. No electron-renderer or service-worker node should arise from them.

Known-good win.loadFile, win.loadURL and navigator.serviceWorker.register syntax should retain its existing findings. This report concerns names with a different final property or identifier, rather than requiring new receiver-type inference.

Actual behavior

All three directory analyses returned successful validated Evidence. The upload fixture produced one electron-renderer node with label upload.html, mechanism call:uploadFile and resolution_status not-found. The download fixture produced one electron-renderer node with mechanism call:downloadURL and resolution_status external. The worker fixture produced one service-worker node with declared_specifier ./sw.js and resolved_path null. Each fixture's Electron summary still reported browser_windows as zero.

The isolated source analyzer independently produced renderer role paths for uploadFile and downloadURL and a service-worker reference for myserviceWorker.register. It also classified the downloadURL argument as a network endpoint. Known-good loader and registration controls retained their findings; unrelated sendFile, fetchURL and myWorker.register controls produced no renderer roles or worker references.

Runtime or environment

Source checkout: a2d8b94dd5, with Node.js 24.18.0 and npm 11.16.0. Verification used source tests and the shared CLI/application boundary. The published rea-agents 6.4.0 runtime was not inspected or executed, so this report makes no release-runtime claim. No live Electron or browser process is needed.

Current recheck at 3ae826ceba found the suffix-recognition and graph-classification logic unchanged and reproduced all three source-analysis cases plus recognized, empty-string and unrelated controls, but the three shared CLI-boundary attempts stopped at worker startup because dist/composition/javascriptAnalysisWorkerProcess.js was absent in the unbuilt checkout, so successful current-boundary execution is not claimed.

Evidence

  • Expected source: docs/javascript-artifact-reconstruction.md:13-53 (Public workflow) documents directory analysis returning static Electron observations and an application graph. docs/javascript-application-graph.md:54-69 (Entities and relationships) distinguishes renderer and service-worker entities from an explicit unknown kind when classification is not justified. src/domain/javascript/javascriptStaticAnalysisTypes.ts:98 defines JavaScriptRolePath.
  • Failure source: the focused tests observed the false entities in the result of runCliJavaScriptApplicationAnalysis. Name-suffix checks: src/domain/javascript/javascriptStaticAnalysisCalls.ts:97 (serviceWorker.register), :103 (loadFile), :117 (loadURL) in inspectCall; src/domain/javascript/javascriptStaticAnalysisHelpers.ts:557 (loadURL) in endpointArgument. Graph entities: src/application/javascript/JavaScriptArtifactGraphFindings.ts:78 (addReference) and :260 (addDiscoveredRole). Line numbers refer to the current-recheck revision; these files are unchanged since the original baseline.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Restoration check

Analyze the same three fixtures. Their graph must contain no electron-renderer or service-worker entity attributed to the unrelated calls, and the static analyzer must emit no renderer role, service-worker reference or downloadURL network endpoint for them. Preserve the known-good win.loadFile, win.loadURL and navigator.serviceWorker.register findings, including the existing empty-string loader inputs. Keep the original ordinary call syntax available to other static/semantic analysis rather than suppressing source analysis to avoid the false classifications.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Three independently reproduced ordinary local calls change the returned application graph by introducing incorrectly typed entities and relationships. The defect is bounded to names sharing recognized API suffixes; no whole-operation failure or original-artifact loss was observed.
  • Workaround status: unverified
  • Workaround basis: The reviewed input contract offers source selection, but excluding an affected file also excludes its valid analysis. No supported way to retain that file's analysis while filtering these classifications was demonstrated.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2678 ## Summary Analyzing an ordinary JavaScript directory adds Electron renderer and service-worker entities for unrelated local functions whose names merely share an API suffix. Locally defined no-op uploadFile and downloadURL functions produce electron-renderer nodes, and a no-op myserviceWorker.register method produces a service-worker node. These false classifications survive application graph validation and appear in the returned analysis Evidence. ## Steps to reproduce Use a checkout at the source baseline under Runtime or environment with its pinned dependencies installed, and build it once with `npm run build:cached`. The shared CLI boundary starts the compiled analysis worker, and `npm run test:local` does not build it for a source test. Create these three independent directory fixtures from the repository root. The fixture contents below were each tested through the production shared CLI boundary. ```sh mkdir -p callee-repro/upload callee-repro/download callee-repro/worker for case in upload download worker; do printf '%s\n' '{"main":"main.cjs"}' > "callee-repro/$case/package.json" done cat > callee-repro/upload/main.cjs <<'JS' function uploadFile() {} uploadFile("upload.html"); JS cat > callee-repro/download/main.cjs <<'JS' function downloadURL() {} downloadURL("https://example.invalid/page"); JS cat > callee-repro/worker/main.cjs <<'JS' const myserviceWorker = { register() {} }; myserviceWorker.register("./sw.js"); JS ``` Save this reproduction test as src/application/javascript/calleeRecognitionRepro.test.ts. It asserts the observed false classifications and prints their declared inputs. It invokes the production boundary used by the CLI, rather than executing any fixture source. ```ts import { resolve } from "node:path"; import { expect, it } from "vitest"; import { runCliJavaScriptApplicationAnalysis } from "../../cli/javascriptApplicationAnalysis.js"; import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js"; it.each([ ["upload", "electron-renderer"], ["download", "electron-renderer"], ["worker", "service-worker"], ])("shows the false classification for %s", async (name, kind) => { const evidence = await runCliJavaScriptApplicationAnalysis({ input_path: resolve("callee-repro", name), }); expect(evidence).toHaveProperty("operation", "analyze_javascript_application"); const result = javascriptApplicationAnalysisResultSchema.parse( (evidence as Record<string, unknown>).normalized_result, ); const nodes = result.graph.nodes.filter( node => node.kind === "electron-renderer" || node.kind === "service-worker", ); expect(nodes.map(node => node.kind)).toEqual([kind]); console.log(JSON.stringify({ fixture: name, nodes: nodes.map(node => ({ kind: node.kind, observations: node.observations.map(observation => ({ label: observation.label, properties: observation.properties, })), })), })); }, 20000); ``` ```sh npm run test:local -- src/application/javascript/calleeRecognitionRepro.test.ts ``` Local verification on the original source baseline ran an equivalent focused test through a serialized source-test launcher, with these same three inputs, boundary calls and graph assertions. The public reproduction above changes only fixture placement and test presentation; its literal command and filename were not rerun. Seven checks passed: three isolated syntax cases, one control check, and three shared CLI-boundary directory cases. No packaged standalone CLI or stdio MCP transport was exercised. ## Expected behavior The static application graph should preserve these ordinary local calls without classifying them as Electron renderer loading or service-worker registration. The fixture functions and method do nothing, and their names are different from the recognized APIs. No electron-renderer or service-worker node should arise from them. Known-good win.loadFile, win.loadURL and navigator.serviceWorker.register syntax should retain its existing findings. This report concerns names with a different final property or identifier, rather than requiring new receiver-type inference. ## Actual behavior All three directory analyses returned successful validated Evidence. The upload fixture produced one electron-renderer node with label upload.html, mechanism call:uploadFile and resolution_status not-found. The download fixture produced one electron-renderer node with mechanism call:downloadURL and resolution_status external. The worker fixture produced one service-worker node with declared_specifier ./sw.js and resolved_path null. Each fixture's Electron summary still reported browser_windows as zero. The isolated source analyzer independently produced renderer role paths for uploadFile and downloadURL and a service-worker reference for myserviceWorker.register. It also classified the downloadURL argument as a network endpoint. Known-good loader and registration controls retained their findings; unrelated sendFile, fetchURL and myWorker.register controls produced no renderer roles or worker references. ## Runtime or environment Source checkout: a2d8b94dd50dab8d966239dd63ab84718aa8b4b4, with Node.js 24.18.0 and npm 11.16.0. Verification used source tests and the shared CLI/application boundary. The published rea-agents 6.4.0 runtime was not inspected or executed, so this report makes no release-runtime claim. No live Electron or browser process is needed. Current recheck at 3ae826ceba6f25b08bce50bcb51001209bc16b57 found the suffix-recognition and graph-classification logic unchanged and reproduced all three source-analysis cases plus recognized, empty-string and unrelated controls, but the three shared CLI-boundary attempts stopped at worker startup because dist/composition/javascriptAnalysisWorkerProcess.js was absent in the unbuilt checkout, so successful current-boundary execution is not claimed. ## Evidence - Expected source: `docs/javascript-artifact-reconstruction.md:13-53` (Public workflow) documents directory analysis returning static Electron observations and an application graph. `docs/javascript-application-graph.md:54-69` (Entities and relationships) distinguishes renderer and service-worker entities from an explicit `unknown` kind when classification is not justified. `src/domain/javascript/javascriptStaticAnalysisTypes.ts:98` defines `JavaScriptRolePath`. - Failure source: the focused tests observed the false entities in the result of `runCliJavaScriptApplicationAnalysis`. Name-suffix checks: `src/domain/javascript/javascriptStaticAnalysisCalls.ts:97` (`serviceWorker.register`), `:103` (`loadFile`), `:117` (`loadURL`) in `inspectCall`; `src/domain/javascript/javascriptStaticAnalysisHelpers.ts:557` (`loadURL`) in `endpointArgument`. Graph entities: `src/application/javascript/JavaScriptArtifactGraphFindings.ts:78` (`addReference`) and `:260` (`addDiscoveredRole`). Line numbers refer to the current-recheck revision; these files are unchanged since the original baseline. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete ## Restoration check Analyze the same three fixtures. Their graph must contain no electron-renderer or service-worker entity attributed to the unrelated calls, and the static analyzer must emit no renderer role, service-worker reference or downloadURL network endpoint for them. Preserve the known-good win.loadFile, win.loadURL and navigator.serviceWorker.register findings, including the existing empty-string loader inputs. Keep the original ordinary call syntax available to other static/semantic analysis rather than suppressing source analysis to avoid the false classifications. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Three independently reproduced ordinary local calls change the returned application graph by introducing incorrectly typed entities and relationships. The defect is bounded to names sharing recognized API suffixes; no whole-operation failure or original-artifact loss was observed. - Workaround status: unverified - Workaround basis: The reviewed input contract offers source selection, but excluding an affected file also excludes its valid analysis. No supported way to retain that file's analysis while filtering these classifications was demonstrated.
bsakaguchi 2026-10-15 18:30:02 +00:00
Author
Owner

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

Verified the reported defect is addressed on main by b91b7e01a54386ec1a5f1296461922db5f3e9724.

Root cause and resolution: Callee recognition now matches complete names/member suffixes, avoiding arbitrary suffix collisions while preserving intended Electron and service-worker calls.

Validation: src/domain/javascript/javascriptStaticAnalysisCalleeBoundary.test.ts — matches complete callee members without suffix collisions: positive complete API members remain recognized while uploadFile, downloadURL, notloadURL, and myserviceWorker.register negatives do not create false classifications.

Evidence: CI run 500e: owner unchanged and assertion passed.

Verification scope: Producer-level source test; no extra public CLI fixture in the acceptance assertion.

Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.

<!-- gh-comment-id:6162504662 --> @morluto commented on GitHub (Oct 14, 2026): Verified the reported defect is addressed on main by b91b7e01a54386ec1a5f1296461922db5f3e9724. Root cause and resolution: Callee recognition now matches complete names/member suffixes, avoiding arbitrary suffix collisions while preserving intended Electron and service-worker calls. Validation: `src/domain/javascript/javascriptStaticAnalysisCalleeBoundary.test.ts` — `matches complete callee members without suffix collisions`: positive complete API members remain recognized while `uploadFile`, `downloadURL`, `notloadURL`, and `myserviceWorker.register` negatives do not create false classifications. Evidence: CI run 500e: owner unchanged and assertion passed. Verification scope: Producer-level source test; no extra public CLI fixture in the acceptance assertion. Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.
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#978
No description provided.