mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
fix(browser): preserve unknown script ownership through reconciliation
This commit is contained in:
1 parent
d397ac7427
commit
d9a855f5cb
5 files changed
+80
-4
No files matched your search
@@ -144,6 +144,10 @@ Script inventory completeness remains a separate reported fact. Unavailable,
|
|||||||
truncated, or attach-limited worker inventory prevents negative code-presence
|
truncated, or attach-limited worker inventory prevents negative code-presence
|
||||||
claims even when the selected page's script inventory is complete. Accepted
|
claims even when the selected page's script inventory is complete. Accepted
|
||||||
positive script correspondences remain loaded.
|
positive script correspondences remain loaded.
|
||||||
|
An Electron script's explicit unknown `frame_scope` preserves its reported
|
||||||
|
frame ID and sourceURL provenance as node properties, but does not link that
|
||||||
|
script to the current frame inventory. Attach-limited script coverage cannot
|
||||||
|
establish negative code-presence claims.
|
||||||
|
|
||||||
None of these states proves feature execution, initialization order,
|
None of these states proves feature execution, initialization order,
|
||||||
reachability, or causality. In particular, `not-observed-in-capture` never means
|
reachability, or causality. In particular, `not-observed-in-capture` never means
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { AnalysisError } from "../../domain/analysisErrorBase.js";
|
|||||||
import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
|
import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
|
||||||
import { sanitizeBrowserUrl } from "../../domain/browserObservation.js";
|
import { sanitizeBrowserUrl } from "../../domain/browserObservation.js";
|
||||||
import { jsonObjectSchema } from "../../domain/jsonValue.js";
|
import { jsonObjectSchema } from "../../domain/jsonValue.js";
|
||||||
import {
|
import type {
|
||||||
type WebRuntimeSource,
|
WebRuntimeSource,
|
||||||
type webRuntimeLocationSchema,
|
webRuntimeLocationSchema,
|
||||||
} from "../../domain/webRuntime.js";
|
} from "../../domain/webRuntime.js";
|
||||||
import type { CdpEvent } from "../CdpConnection.js";
|
import type { CdpEvent } from "../CdpConnection.js";
|
||||||
import type { CdpRuntimeSession } from "./CdpRuntimeSession.js";
|
import type { CdpRuntimeSession } from "./CdpRuntimeSession.js";
|
||||||
|
|||||||
@@ -506,10 +506,12 @@ const assertRuntimeParameters = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const scriptsComplete = (completeness: {
|
const scriptsComplete = (completeness: {
|
||||||
|
readonly attach_limited_sections: readonly string[];
|
||||||
readonly truncated_sections: readonly string[];
|
readonly truncated_sections: readonly string[];
|
||||||
readonly unavailable_sections: readonly string[];
|
readonly unavailable_sections: readonly string[];
|
||||||
readonly dropped_events: { readonly scripts: number };
|
readonly dropped_events: { readonly scripts: number };
|
||||||
}): boolean =>
|
}): boolean =>
|
||||||
|
!completeness.attach_limited_sections.includes("scripts") &&
|
||||||
!completeness.truncated_sections.includes("scripts") &&
|
!completeness.truncated_sections.includes("scripts") &&
|
||||||
!completeness.unavailable_sections.includes("scripts") &&
|
!completeness.unavailable_sections.includes("scripts") &&
|
||||||
completeness.dropped_events.scripts === 0;
|
completeness.dropped_events.scripts === 0;
|
||||||
|
|||||||
@@ -157,7 +157,10 @@ const scriptEntities = (
|
|||||||
nodeKind: "runtime-script-instance",
|
nodeKind: "runtime-script-instance",
|
||||||
runtimeKey: script.script_key,
|
runtimeKey: script.script_key,
|
||||||
targetKey: capture.inspection.target.target_id,
|
targetKey: capture.inspection.target.target_id,
|
||||||
frameKey: script.frame_id,
|
frameKey:
|
||||||
|
"frame_scope" in script && script.frame_scope === "unknown"
|
||||||
|
? null
|
||||||
|
: script.frame_id,
|
||||||
scriptKey: script.script_key,
|
scriptKey: script.script_key,
|
||||||
location,
|
location,
|
||||||
staticKind: "javascript",
|
staticKind: "javascript",
|
||||||
@@ -176,6 +179,15 @@ const scriptEntities = (
|
|||||||
...("reported_url" in script && script.reported_url !== undefined
|
...("reported_url" in script && script.reported_url !== undefined
|
||||||
? { reported_url: script.reported_url }
|
? { reported_url: script.reported_url }
|
||||||
: {}),
|
: {}),
|
||||||
|
...("frame_scope" in script && script.frame_scope !== undefined
|
||||||
|
? {
|
||||||
|
frame_scope: script.frame_scope,
|
||||||
|
reported_frame_id: script.frame_id,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...("has_source_url" in script && script.has_source_url !== undefined
|
||||||
|
? { has_source_url: script.has_source_url }
|
||||||
|
: {}),
|
||||||
cdp_hash: script.cdp_hash,
|
cdp_hash: script.cdp_hash,
|
||||||
length: script.length,
|
length: script.length,
|
||||||
is_module: script.is_module,
|
is_module: script.is_module,
|
||||||
|
|||||||
+58
@@ -11,6 +11,7 @@ import { reconcileJavaScriptRuntimeEvidence } from "../../../../src/application/
|
|||||||
import { createEvidence } from "../../../../src/domain/evidence.js";
|
import { createEvidence } from "../../../../src/domain/evidence.js";
|
||||||
import { mappedRuntimePaths } from "../../../../src/domain/javascript/javascriptRuntimeStaticCandidates.js";
|
import { mappedRuntimePaths } from "../../../../src/domain/javascript/javascriptRuntimeStaticCandidates.js";
|
||||||
import { projectRuntimeCaptures } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationRuntime.js";
|
import { projectRuntimeCaptures } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationRuntime.js";
|
||||||
|
import { parseRuntimeCaptures } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js";
|
||||||
import { electronPageInspectionSchema } from "../../../../src/domain/javascript/electronObservation.js";
|
import { electronPageInspectionSchema } from "../../../../src/domain/javascript/electronObservation.js";
|
||||||
import {
|
import {
|
||||||
readRuntimeReconciliationInput,
|
readRuntimeReconciliationInput,
|
||||||
@@ -263,6 +264,63 @@ it("preserves positive script matches without inventing worker absence when work
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves unknown Electron frame provenance without linking it to an authorized frame", async () => {
|
||||||
|
const root = await applicationFixture();
|
||||||
|
const recorded = electronRuntimeEvidence(root, SOURCE);
|
||||||
|
const inspection = electronPageInspectionSchema.parse(
|
||||||
|
recorded.normalized_result,
|
||||||
|
);
|
||||||
|
const evidence = createEvidence(undefined, recorded.provider, {
|
||||||
|
predicateType: recorded.predicate_type,
|
||||||
|
operation: recorded.operation,
|
||||||
|
parameters: recorded.parameters,
|
||||||
|
confidence: recorded.confidence,
|
||||||
|
authority: recorded.authority,
|
||||||
|
result: {
|
||||||
|
...inspection,
|
||||||
|
completeness: {
|
||||||
|
...inspection.completeness,
|
||||||
|
status: "attach_limited",
|
||||||
|
conditions: ["attach_limited"],
|
||||||
|
attach_limited_sections: ["scripts"],
|
||||||
|
},
|
||||||
|
scripts: {
|
||||||
|
...inspection.scripts,
|
||||||
|
items: inspection.scripts.items.map((script) => ({
|
||||||
|
...script,
|
||||||
|
frame_scope: "unknown",
|
||||||
|
has_source_url: true,
|
||||||
|
reported_url: "file:///reported-label.js",
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const captures = parseRuntimeCaptures([evidence]);
|
||||||
|
expect(captures[0]?.scriptsCompleteWithinScope).toBe(false);
|
||||||
|
const projected = projectRuntimeCaptures(captures);
|
||||||
|
const script = projected.entities.find(({ kind }) => kind === "script");
|
||||||
|
expect(script?.frameKey).toBeNull();
|
||||||
|
expect(script?.node.properties).toMatchObject({
|
||||||
|
frame_scope: "unknown",
|
||||||
|
reported_frame_id: inspection.scripts.items[0]?.frame_id,
|
||||||
|
has_source_url: true,
|
||||||
|
reported_url: "file:///reported-label.js",
|
||||||
|
});
|
||||||
|
const frameIds = new Set(
|
||||||
|
projected.entities
|
||||||
|
.filter(({ kind }) => kind === "frame")
|
||||||
|
.map(({ node }) => node.node_id),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
projected.edges.some(
|
||||||
|
(edge) =>
|
||||||
|
edge.relation === "contains" &&
|
||||||
|
frameIds.has(edge.source_node_id) &&
|
||||||
|
edge.target_node_id === script?.node.node_id,
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it("reconciles active Electron as a partial target-only runtime capture", async () => {
|
it("reconciles active Electron as a partial target-only runtime capture", async () => {
|
||||||
const fixture = await applicationFixture();
|
const fixture = await applicationFixture();
|
||||||
const staticEvidence = await analyzeFixture(fixture);
|
const staticEvidence = await analyzeFixture(fixture);
|
||||||
|
|||||||
Reference in new issue
Block a user