import { mkdir, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { expect, it } from "vitest"; import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js"; import { createElectronActiveEvidence } from "../../../../src/application/javascript/ElectronActiveEvidence.js"; import { reconcileJavaScriptRuntimeEvidence } from "../../../../src/application/javascript/JavaScriptRuntimeReconciliationService.js"; import { createEvidence } from "../../../../src/domain/evidence.js"; import { mappedRuntimePaths } from "../../../../src/domain/javascript/javascriptRuntimeStaticCandidates.js"; import { projectRuntimeCaptures } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationRuntime.js"; import { electronPageInspectionSchema } from "../../../../src/domain/javascript/electronObservation.js"; import { parseRuntimeReconciliationInput, reconcileJavaScriptRuntime, } from "../../../../src/domain/javascript/javascriptRuntimeReconciliation.js"; import { reconcileJavaScriptRuntimeInputSchema } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationSchemas.js"; import { javascriptRuntimeReconciliationResultSchema } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationSchemas.js"; import { electronActiveObservationInputSchema } from "../../../../src/domain/javascript/electronActiveObservation.js"; import { createElectronActiveObservationFixtureResult } from "../../../../src/domain/javascript/electronActiveObservation.fixture.js"; import { SOURCE, applicationFixture, analyzeFixture, electronRuntimeEvidence, } from "../../../fixtures/javascriptRuntimeReconciliation.js"; const reconcileInput = (input: unknown) => reconcileJavaScriptRuntime( parseRuntimeReconciliationInput( reconcileJavaScriptRuntimeInputSchema.parse(input), ), ); it("preserves source-capture input paths for runtime Evidence", async () => { const root = await applicationFixture(); const application = await analyzeFixture(root); const runtime = electronRuntimeEvidence(root, SOURCE); const invalidRuntime = createEvidence(undefined, runtime.provider, { predicateType: runtime.predicate_type, operation: runtime.operation, parameters: { ...runtime.parameters, include_script_sources: false }, result: runtime.normalized_result, confidence: runtime.confidence, authority: runtime.authority, }); const result = reconcileJavaScriptRuntimeEvidence({ static_layers: [{ role: "application", analysis: application }], runtime_observations: [invalidRuntime], }); expect(result).toMatchObject({ ok: false, error: { _tag: "AnalysisInputError", issues: [ { path: [ "runtime_observations", 0, "parameters", "include_script_sources", ], reason: "invalid_value", message: "Runtime Evidence contains source without source-capture selection", }, ], }, }); }); it("reconciles runtime scripts inside dot-prefixed child directories", async () => { const root = await applicationFixture(); await mkdir(join(root, "..cache")); await writeFile(join(root, "..cache", "app.js"), SOURCE); const result = reconcileInput({ static_layers: [ { role: "application", analysis: await analyzeFixture(root) }, ], runtime_observations: [ electronRuntimeEvidence(root, SOURCE, { scriptFile: "..cache/app.js", includeWorker: false, }), ], }); expect(result.reconciliations).toEqual( expect.arrayContaining([ expect.objectContaining({ entity_kind: "script", status: "matched", basis: "content-and-location", }), ]), ); }); it("matches renderer, frame, script bytes, and worker without claiming execution", async () => { const fixture = await applicationFixture(); const staticEvidence = await analyzeFixture(fixture); const runtimeEvidence = electronRuntimeEvidence(fixture, SOURCE); const result = reconcileInput({ static_layers: [{ role: "application", analysis: staticEvidence }], runtime_observations: [runtimeEvidence], }); expect(() => javascriptRuntimeReconciliationResultSchema.parse(result), ).not.toThrow(); expect(result.source_map_authority).toMatchObject({ used_for_primary_matching: false, static_layer_count: 1, runtime_script_declarations: 0, }); expect(result.summary).toMatchObject({ runtime_targets: 1, runtime_frames: 1, runtime_scripts: 1, runtime_workers: 1, matched: 2, ambiguous: 2, unmatched: 0, }); expect(result.reconciliations).toEqual( expect.arrayContaining([ expect.objectContaining({ entity_kind: "script", status: "matched", basis: "content-and-location", }), expect.objectContaining({ entity_kind: "worker", status: "matched", basis: "artifact-path", }), expect.objectContaining({ entity_kind: "target", status: "ambiguous", reason: "ambiguous-static-candidates", }), ]), ); const matched = result.reconciliations.find( ({ status }) => status === "matched", ); if (matched === undefined) throw new TypeError("Expected one matched runtime reconciliation"); expect( javascriptRuntimeReconciliationResultSchema.safeParse({ ...result, reconciliations: [{ ...matched, static_node_id: null }], }).success, ).toBe(false); expect(result.static_load_states).toEqual( expect.arrayContaining([ expect.objectContaining({ kind: "javascript-asset", status: "loaded", }), ]), ); expect(result.limitations.join(" ")).toMatch( /not reported as executed|not code reachability/u, ); expect( result.graph.edges .filter(({ relation }) => relation === "observed_as") .every( ({ evidence }) => evidence.authority === "cross-layer-reconciliation" && evidence.state === "inferred", ), ).toBe(true); const worker = result.reconciliations.find( ({ entity_kind: kind }) => kind === "worker", ); const frame = result.reconciliations.find( ({ entity_kind: kind }) => kind === "frame", ); expect(result.graph.edges).toContainEqual( expect.objectContaining({ source_node_id: frame?.runtime_node_id, target_node_id: worker?.runtime_node_id, relation: "contains", }), ); }); it("keeps static load states unknown when one scoped capture omits scripts", async () => { const fixture = await applicationFixture(); const staticEvidence = await analyzeFixture(fixture); const result = reconcileInput({ static_layers: [{ role: "application", analysis: staticEvidence }], runtime_observations: [ electronRuntimeEvidence(fixture, SOURCE, { includeWorker: false, targetId: "target-complete", }), electronRuntimeEvidence(fixture, SOURCE, { includeWorker: false, scriptsUnavailable: true, targetId: "target-incomplete", }), ], }); expect( result.runtime_captures.map( ({ scripts_complete_within_scope }) => scripts_complete_within_scope, ), ).toEqual(expect.arrayContaining([false, true])); expect(result.summary.static_not_observed).toBe(0); expect(result.static_load_states).toEqual( expect.arrayContaining([ expect.objectContaining({ status: "unknown", reason: "static-or-runtime-coverage-incomplete", }), ]), ); }); it("reports a captured digest disagreement instead of accepting a path match", async () => { const fixture = await applicationFixture(); const staticEvidence = await analyzeFixture(fixture); const runtimeEvidence = electronRuntimeEvidence( fixture, "export const observed = 'different';\n", ); const result = reconcileInput({ static_layers: [{ role: "application", analysis: staticEvidence }], runtime_observations: [runtimeEvidence], }); const script = result.reconciliations.find( ({ entity_kind: kind }) => kind === "script", ); expect(script).toMatchObject({ status: "unmatched", reason: "captured-content-disagrees-with-static-location", }); expect(script?.candidate_static_nodes).toHaveLength(1); }); it("reconciles active Electron as a partial target-only runtime capture", async () => { const fixture = await applicationFixture(); const staticEvidence = await analyzeFixture(fixture); const applicationPath = join(fixture, "main.js"); const input = { ...electronActiveObservationInputSchema.parse({ executable_path: process.execPath, application_path: applicationPath, application_root: fixture, actions: [], }), application_root: fixture, }; const runtimeEvidence = createElectronActiveEvidence( input, createElectronActiveObservationFixtureResult(applicationPath), { id: "rea-playwright-electron-active", name: "REA Playwright active Electron observation provider", version: "1", }, ); const result = reconcileInput({ static_layers: [{ role: "application", analysis: staticEvidence }], runtime_observations: [runtimeEvidence], }); expect(result.runtime_captures).toMatchObject([ { kind: "electron-active", scripts: 0, frames: 0, workers: 0, scripts_complete_within_scope: false, }, ]); expect(result.coverage.status).toBe("partial"); expect(result.limitations.join(" ")).toMatch( /incomplete|not reported as executed/u, ); }); it("commits complete Electron actions independently from selected arguments", async () => { const fixture = await applicationFixture(); const applicationPath = join(fixture, "main.js"); const makeInput = (secret: string, selector: string) => ({ ...electronActiveObservationInputSchema.parse({ executable_path: process.execPath, application_path: applicationPath, application_root: fixture, args: ["--token", secret], actions: [ { step_id: "click", kind: "click", selector }, { step_id: "settle", kind: "wait", duration_ms: 37 }, { step_id: "open", kind: "deep-link", delivery: "second-instance", url: "rea-fixture://open/item?token=selected", }, ], }), application_root: fixture, }); const provider = { id: "rea-playwright-electron-active", name: "REA Playwright active Electron observation provider", version: "1", }; const first = createElectronActiveEvidence( makeInput("first-secret", "#first-secret"), createElectronActiveObservationFixtureResult(applicationPath), provider, ); const second = createElectronActiveEvidence( makeInput("first-secret", "#second-secret"), createElectronActiveObservationFixtureResult(applicationPath), provider, ); expect(first.parameters.scenario_sha256).not.toBe( second.parameters.scenario_sha256, ); expect(JSON.stringify(first)).toContain("first-secret"); expect(first.parameters.actions).toEqual([ { step_id: "click", kind: "click", selector: "#first-secret", window_index: 0, }, { step_id: "settle", kind: "wait", duration_ms: 37 }, { step_id: "open", kind: "deep-link", delivery: "second-instance", url: "rea-fixture://open/item?token=selected", }, ]); expect(first.parameters.args).toEqual(["--token", "first-secret"]); }); it("imports an operator-provided cache layer through an explicit file mapping", async () => { const application = await applicationFixture(); const cache = await createTestTempDirectory("rea-runtime-cache-static-"); const runtimeCache = await createTestTempDirectory("rea-runtime-cache-live-"); const cacheSource = SOURCE; await mkdir(join(cache, "mapped")); await Promise.all([ writeFile(join(cache, "mapped", "chunk.js"), cacheSource), writeFile(join(cache, "outside.js"), "export const outside = true;\n"), writeFile(join(runtimeCache, "chunk.js"), cacheSource), writeFile(join(runtimeCache, "index.html"), ""), ]); const applicationEvidence = await analyzeFixture(application); const cacheEvidence = await analyzeFixture(cache); const runtimeEvidence = electronRuntimeEvidence(runtimeCache, cacheSource, { scriptFile: "chunk.js", includeWorker: false, }); const result = reconcileInput({ static_layers: [ { role: "application", analysis: applicationEvidence }, { role: "cache", analysis: cacheEvidence, runtime_mappings: [ { kind: "file-root", root: runtimeCache, artifact_prefix: "mapped", }, ], }, ], runtime_observations: [runtimeEvidence], }); const script = result.reconciliations.find( ({ entity_kind: kind }) => kind === "script", ); const cacheLayer = result.static_layers.find(({ role }) => role === "cache"); expect(script).toMatchObject({ status: "matched", basis: "content-and-location", static_layer_id: cacheLayer?.layer_id, }); const outside = result.graph.nodes.find( (node) => node.kind === "javascript-asset" && node.observations.some( ({ properties }) => properties.path === "outside.js", ), ); expect( result.static_load_states.find( ({ static_node_id: nodeId }) => nodeId === outside?.node_id, ), ).toMatchObject({ status: "unknown", reason: "layer-outside-runtime-scope", }); const sharedFile = result.graph.nodes.find( ({ observations }) => observations.some(({ properties }) => properties.path === "app.js") && observations.some( ({ properties }) => properties.path === "mapped/chunk.js", ), ); expect( sharedFile?.observations.map(({ properties }) => properties.path), ).toEqual(expect.arrayContaining(["app.js", "mapped/chunk.js"])); }); const sourceFreeRuntime = (runtimeRoot: string, scriptFile: string) => { const runtime = electronRuntimeEvidence(runtimeRoot, "", { scriptFile, sourceIncluded: false, includeWorker: false, }); const observation = electronPageInspectionSchema.parse( runtime.normalized_result, ); for (const script of observation.scripts.items) script.source = { included: false, reason: "not-requested" }; return createEvidence(undefined, runtime.provider, { operation: runtime.operation, predicateType: runtime.predicate_type, parameters: runtime.parameters, result: observation, confidence: runtime.confidence, authority: runtime.authority, }); }; const reconcileScriptLocation = ( application: Awaited>, root: string, scriptFile: string, runtimeRoot = root, ) => { return reconcileInput({ static_layers: [ { role: "application", analysis: application, runtime_mappings: runtimeRoot === root ? [] : [{ kind: "file-root", root: runtimeRoot, artifact_prefix: "" }], }, ], runtime_observations: [sourceFreeRuntime(runtimeRoot, scriptFile)], }).reconciliations.find(({ entity_kind }) => entity_kind === "script"); }; it.skipIf(process.platform === "win32")( "keeps distinct POSIX backslash and slash script locations separate", async () => { const root = await createTestTempDirectory("rea-backslash-runtime-"); const literal = "literal\\name.js"; await writeFile(join(root, literal), "export const marker = 'literal';\n"); const application = await analyzeFixture(root); expect( reconcileScriptLocation(application, root, "literal/name.js"), ).toMatchObject({ status: "unmatched" }); expect(reconcileScriptLocation(application, root, literal)).toMatchObject({ status: "matched", basis: "artifact-path", }); }, ); it.skipIf(process.platform === "win32")( "does not make POSIX literal and slash paths ambiguous, including Windows runtime mappings", async () => { const root = await createTestTempDirectory("rea-backslash-runtime-pair-"); const literal = "literal\\name.js"; await mkdir(join(root, "literal")); await writeFile(join(root, literal), "export const marker = 'literal';\n"); await writeFile( join(root, "literal", "name.js"), "export const marker = 'slash';\n", ); const application = await analyzeFixture(root); const slash = reconcileScriptLocation(application, root, "literal/name.js"); const backslash = reconcileScriptLocation(application, root, literal); expect(slash).toMatchObject({ status: "matched", basis: "artifact-path" }); expect(backslash).toMatchObject({ status: "matched", basis: "artifact-path", }); expect(slash?.static_node_id).not.toBe(backslash?.static_node_id); // These recorded Windows paths exercise matching only, not native Windows IO. expect( reconcileScriptLocation( application, root, "literal\\name.js", "C:\\runtime", ), ).toMatchObject({ status: "matched", static_node_id: slash?.static_node_id, }); }, ); it.skipIf(process.platform === "win32")( "preserves URL-prefix path semantics separately from logical artifact names", async () => { const root = await createTestTempDirectory("rea-backslash-runtime-url-"); await writeFile( join(root, "literal\\name.js"), "export const marker = 42;\n", ); const analysis = await analyzeFixture(root); const parsed = parseRuntimeReconciliationInput( reconcileJavaScriptRuntimeInputSchema.parse({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "url-prefix", prefix: "https://example.test/assets/", artifact_prefix: "", }, ], }, ], runtime_observations: [sourceFreeRuntime(root, "literal\\name.js")], }), ); const layer = parsed.layers[0]; const entity = projectRuntimeCaptures(parsed.captures).entities.find( ({ kind }) => kind === "script", ); if (layer === undefined || entity === undefined) throw new Error("Expected parsed static layer and runtime script"); const mapped = (value: string) => mappedRuntimePaths(layer, { ...entity, location: { kind: "url", value }, }).map(({ path }) => path); expect(mapped("https://example.test/assets/literal%5Cname.js")).toEqual([ "literal\\name.js", ]); expect(mapped("https://example.test/assets/literal/name.js")).toEqual([ "literal/name.js", ]); expect(mapped("https://example.test/assets/literal\\name.js")).toEqual([ "literal/name.js", ]); expect(mapped("https://other.test/assets/literal/name.js")).toEqual([]); expect(mapped("https://example.test/assets/%2e%2e/outside.js")).toEqual([]); }, ); const rendererCapture = (runtimeRoot: string, filePath: string) => { const runtime = sourceFreeRuntime(runtimeRoot, "main.cjs"); const observation = electronPageInspectionSchema.parse( runtime.normalized_result, ); observation.target.file_path = filePath; for (const frame of observation.frames) frame.file_path = filePath; return createEvidence(undefined, runtime.provider, { operation: runtime.operation, predicateType: runtime.predicate_type, parameters: runtime.parameters, result: observation, confidence: runtime.confidence, authority: runtime.authority, }); }; it.skipIf(process.platform === "win32")( "interprets raw loadFile declarations using the captured native path format", async () => { const root = await createTestTempDirectory( "rea-native-loadfile-declaration-", ); await mkdir(join(root, "dist")); await writeFile(join(root, "dist", "index.html"), "slash file"); await writeFile(join(root, "dist\\index.html"), "literal file"); await writeFile( join(root, "main.cjs"), `const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile(${JSON.stringify("dist\\index.html")});`, ); const analysis = await analyzeFixture(root); const reconcileTarget = (runtimeRoot: string, path: string) => reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: runtimeRoot, artifact_prefix: "" }, ], }, ], runtime_observations: [rendererCapture(runtimeRoot, path)], }).reconciliations.find(({ entity_kind }) => entity_kind === "target"); // These Windows paths are recorded data, not native Windows execution. expect( reconcileTarget("C:\\runtime", "C:\\runtime\\dist\\index.html"), ).toMatchObject({ status: "matched" }); expect(reconcileTarget(root, join(root, "dist\\index.html"))).toMatchObject( { status: "matched" }, ); expect( reconcileTarget(root, join(root, "dist", "index.html")), ).toMatchObject({ status: "unmatched" }); }, ); it.skipIf(process.platform === "win32").each(["literal\\dir", "literal%5Cdir"])( "maps a runtime root to the exact logical artifact prefix %j", async (prefix) => { const root = await createTestTempDirectory("rea-literal-artifact-prefix-"); await mkdir(join(root, prefix)); await writeFile( join(root, prefix, "app.js"), "export const marker = 42;\n", ); const analysis = await analyzeFixture(root); const result = reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: "/deployed", artifact_prefix: prefix }, ], }, ], runtime_observations: [sourceFreeRuntime("/deployed", "app.js")], }); expect( result.reconciliations.find( ({ entity_kind }) => entity_kind === "script", ), ).toMatchObject({ status: "matched", basis: "operator-file-mapping" }); }, ); it.skipIf(process.platform === "win32")( "uses resolved artifact paths instead of a raw declaration alias", async () => { const root = await createTestTempDirectory("rea-resolved-loadfile-alias-"); const directory = "literal\\dir"; await mkdir(join(root, directory)); await writeFile(join(root, directory, "index.html"), "owned target"); await writeFile(join(root, "index.html"), "different target"); await writeFile( join(root, directory, "package.json"), JSON.stringify({ name: "literal-renderer", version: "1.0.0", renderer: "./index.html", }), ); const analysis = await analyzeFixture(root); const reconcileTarget = (path: string) => reconcileInput({ static_layers: [{ analysis, role: "application" }], runtime_observations: [rendererCapture(root, path)], }).reconciliations.find(({ entity_kind }) => entity_kind === "target"); expect(reconcileTarget(join(root, directory, "index.html"))).toMatchObject({ status: "matched", }); expect(reconcileTarget(join(root, "index.html"))).toMatchObject({ status: "unmatched", }); }, ); it("rejects unsafe logical artifact prefixes without decoding literal names", async () => { const root = await createTestTempDirectory("rea-prefix-admission-"); await writeFile(join(root, "app.js"), "export const marker = 42;\n"); const analysis = await analyzeFixture(root); const accepts = (artifact_prefix: string) => reconcileJavaScriptRuntimeInputSchema.safeParse({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: "/deployed", artifact_prefix }, ], }, ], runtime_observations: [sourceFreeRuntime("/deployed", "app.js")], }).success; for (const prefix of [ "\0", "/absolute", ".", "..", "a/../b", "a//b", "a/", "./a", ]) expect(accepts(prefix), prefix).toBe(false); for (const prefix of ["", "literal\\dir", "literal%5Cdir", "literal%2Fdir"]) expect(accepts(prefix), prefix).toBe(true); }); it.skipIf(process.platform === "win32")( "keeps a leading backslash declaration literal only for POSIX captures", async () => { const root = await createTestTempDirectory("rea-leading-loadfile-"); await writeFile(join(root, "\\index.html"), "literal target"); await writeFile( join(root, "main.cjs"), `const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile(${JSON.stringify("\\index.html")});`, ); const analysis = await analyzeFixture(root); const reconcileTarget = (runtimeRoot: string, path: string) => reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: runtimeRoot, artifact_prefix: "" }, ], }, ], runtime_observations: [rendererCapture(runtimeRoot, path)], }).reconciliations.find(({ entity_kind }) => entity_kind === "target"); expect(reconcileTarget(root, join(root, "\\index.html"))).toMatchObject({ status: "matched", }); expect( reconcileTarget("C:\\runtime", "C:\\runtime\\index.html"), ).toMatchObject({ status: "unmatched" }); }, ); it("keeps a raw nested loadFile target application-relative when the producer also resolves a nested decoy", async () => { const root = await createTestTempDirectory("rea-raw-loadfile-ownership-"); await mkdir(join(root, "dist")); await mkdir(join(root, "sub", "dist"), { recursive: true }); await writeFile(join(root, "dist", "index.html"), "application target"); await writeFile(join(root, "sub", "dist", "index.html"), "nested decoy"); await writeFile( join(root, "sub", "main.cjs"), "const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile('dist/index.html');", ); const analysis = await analyzeFixture(root); const reconcileTarget = (path: string) => reconcileInput({ static_layers: [{ analysis, role: "application" }], runtime_observations: [rendererCapture(root, path)], }).reconciliations.find(({ entity_kind }) => entity_kind === "target"); expect(reconcileTarget(join(root, "dist", "index.html"))).toMatchObject({ status: "matched", }); expect( reconcileTarget(join(root, "sub", "dist", "index.html")), ).toMatchObject({ status: "unmatched" }); }); it .skipIf(process.platform === "win32") .each(["app", "literal\\app", "café", "cafe\u0301"])( "maps raw renderer declarations through the logical application prefix %j", async (prefix) => { const root = await createTestTempDirectory("rea-prefixed-native-renderer-"); await mkdir(join(root, prefix, "dist"), { recursive: true }); await writeFile( join(root, prefix, "dist", "index.html"), "application target", ); await writeFile( join(root, prefix, "main.cjs"), "const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile('dist/index.html');", ); const analysis = await analyzeFixture(root); const reconcileTarget = (runtimeRoot: string, path: string) => reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: runtimeRoot, artifact_prefix: prefix }, ], }, ], runtime_observations: [rendererCapture(runtimeRoot, path)], }).reconciliations.find(({ entity_kind }) => entity_kind === "target"); expect( reconcileTarget("/deployed", "/deployed/dist/index.html"), ).toMatchObject({ status: "matched", basis: "operator-file-mapping" }); expect( reconcileTarget("C:\\deployed", "C:\\deployed\\dist\\index.html"), ).toMatchObject({ status: "matched", basis: "operator-file-mapping" }); expect(reconcileTarget("/deployed", "/deployed/index.html")).toMatchObject({ status: "unmatched", }); }, ); it("confines raw renderer declarations to the operator-selected artifact prefix", async () => { const root = await createTestTempDirectory("rea-native-prefix-isolation-"); for (const app of ["appA", "appB"]) { await mkdir(join(root, app, "dist"), { recursive: true }); await writeFile(join(root, app, "dist", "index.html"), app); await writeFile( join(root, app, "main.cjs"), "const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile('dist/index.html');", ); } const analysis = await analyzeFixture(root); const result = reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: "/deployed", artifact_prefix: "appA" }, ], }, ], runtime_observations: [ rendererCapture("/deployed", "/deployed/dist/index.html"), ], }); const target = result.reconciliations.find( ({ entity_kind }) => entity_kind === "target", ); expect(target).toMatchObject({ status: "matched", candidate_static_count: 1, }); const node = result.graph.nodes.find( ({ node_id }) => node_id === target?.static_node_id, ); expect( node?.observations.flatMap(({ evidence }) => evidence.location.available && evidence.location.value.kind === "source-range" ? [evidence.location.value.source] : [], ), ).toEqual(["appA/main.cjs"]); }); it("retains uncertainty for overlapping file mappings with distinct application interpretations", async () => { const root = await createTestTempDirectory("rea-overlapping-native-prefix-"); await mkdir(join(root, "app", "dist"), { recursive: true }); await writeFile(join(root, "app", "dist", "index.html"), "shared target"); for (const [path, declaration] of [ ["app/main.cjs", "dist/index.html"], ["app/dist/main.cjs", "index.html"], ]) await writeFile( join(root, path!), `const { BrowserWindow } = require('electron'); const win = new BrowserWindow(); win.loadFile(${JSON.stringify(declaration)});`, ); const analysis = await analyzeFixture(root); const result = reconcileInput({ static_layers: [ { analysis, role: "application", runtime_mappings: [ { kind: "file-root", root: "/deployed", artifact_prefix: "app" }, { kind: "file-root", root: "/deployed/dist", artifact_prefix: "app/dist", }, ], }, ], runtime_observations: [ rendererCapture("/deployed", "/deployed/dist/index.html"), ], }); expect( result.reconciliations.find(({ entity_kind }) => entity_kind === "target"), ).toMatchObject({ status: "ambiguous", confidence: "unknown", candidate_static_count: 2, }); });