refactor(javascript): parse runtime evidence into one verified owner

This commit is contained in:
morluto committed 2026-10-10 03:52:35 +08:00
1 parent 415145d04f
commit 006b295f1d
15 files changed
+839 -512

No files matched your search

@@ -2,22 +2,42 @@ import { classifyStaticLoadStates } from "./javascriptRuntimeLoadState.js";
import { buildReconciledApplicationGraph } from "./javascriptRuntimeReconciliationGraph.js";
import { reconcileRuntimeEntities } from "./javascriptRuntimeReconciliationMatching.js";
import {
parseRuntimeCaptures,
parseStaticLayers,
type ParsedStaticLayer,
} from "./javascriptRuntimeReconciliationParsing.js";
import {
parseRuntimeCaptures,
type ParsedRuntimeCapture,
} from "./javascriptRuntimeReconciliationCaptureParsing.js";
import { createJavaScriptRuntimeReconciliationResult } from "./javascriptRuntimeReconciliationResult.js";
import type { JavaScriptRuntimeReconciliationResult } from "./javascriptRuntimeReconciliationSchemas.js";
import { reconcileJavaScriptRuntimeInputSchema } from "./javascriptRuntimeReconciliationSchemas.js";
import type { ReconcileJavaScriptRuntimeInput } from "./javascriptRuntimeReconciliationSchemas.js";
import { projectRuntimeCaptures } from "./javascriptRuntimeReconciliationRuntime.js";
import { collectStaticRuntimeCandidates } from "./javascriptRuntimeStaticCandidates.js";
/** Verified caller input and the static and runtime facts parsed from it. */
export interface ParsedRuntimeReconciliationInput {
readonly input: ReconcileJavaScriptRuntimeInput;
readonly layers: readonly ParsedStaticLayer[];
readonly captures: readonly ParsedRuntimeCapture[];
}
/** Parse caller Evidence once into the owner consumed by reconciliation. */
export const parseRuntimeReconciliationInput = (
input: ReconcileJavaScriptRuntimeInput,
): ParsedRuntimeReconciliationInput => ({
input,
layers: parseStaticLayers(input.static_layers, ["static_layers"]),
captures: parseRuntimeCaptures(input.runtime_observations, [
"runtime_observations",
]),
});
/** Reconcile static JAG layers with authorized passive CDP Evidence. */
export const reconcileJavaScriptRuntime = (
input: unknown,
parsed: ParsedRuntimeReconciliationInput,
): JavaScriptRuntimeReconciliationResult => {
const parsed = reconcileJavaScriptRuntimeInputSchema.parse(input);
const layers = parseStaticLayers(parsed.static_layers);
const captures = parseRuntimeCaptures(parsed.runtime_observations);
const { layers, captures } = parsed;
const runtime = projectRuntimeCaptures(captures);
const candidates = collectStaticRuntimeCandidates(layers);
const matching = reconcileRuntimeEntities({
@@ -3,6 +3,10 @@ import { isAbsolute } from "node:path";
import { digestCanonicalValue } from "../canonicalDigest.js";
import { isPathWithinRoot } from "../localPath.js";
import { z } from "zod";
import {
invalidInput,
parseAtPath,
} from "./javascriptRuntimeReconciliationInputValidation.js";
import {
classifyBrowserCompleteness,
@@ -13,23 +17,30 @@ import {
type ElectronActiveObservationResult,
} from "./electronActiveObservation.js";
import type { Evidence } from "../evidence.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationCaptureParsing.js";
/** Parse active Electron Evidence as a bounded, target-only runtime capture. */
export const parseActiveElectronCapture = (
evidence: Evidence,
): ParsedRuntimeCapture => {
assertIdentity(evidence);
const result = electronActiveObservationResultSchema.parse(
const result = parseAtPath(
(value) => electronActiveObservationResultSchema.parse(value),
evidence.normalized_result,
["normalized_result"],
);
const parameters = parseAtPath(
(value) =>
z
.object({
application_path: absolutePathSchema,
application_root: absolutePathSchema,
})
.passthrough()
.parse(value),
evidence.parameters,
["parameters"],
);
const parameters = z
.object({
application_path: absolutePathSchema,
application_root: absolutePathSchema,
})
.passthrough()
.parse(evidence.parameters);
if (
result.application.application_path !== parameters.application_path ||
!isPathWithinRoot(
@@ -37,7 +48,8 @@ export const parseActiveElectronCapture = (
result.application.application_path,
)
)
throw new TypeError(
throw invalidInput(
["normalized_result", "application", "application_path"],
"Active Electron Evidence application path disagrees with its configured root",
);
return {
@@ -62,11 +74,11 @@ const assertIdentity = (evidence: Evidence): void => {
evidence.authority !== "controlled-replay" ||
evidence.confidence !== "observed"
)
throw new TypeError(
throw invalidInput(
[],
"Evidence does not match the supported capture_electron_scenario contract",
);
};
const normalizeInspection = (
result: ElectronActiveObservationResult,
): {
@@ -0,0 +1,481 @@
import { z } from "zod";
import {
browserAllowedOriginsSchema,
browserEndpointSchema,
} from "../browserObservation.js";
import {
webPageInspectionSchema,
type WebPageInspection,
} from "../browserObservationSchemas.js";
import {
classifyBrowserCompleteness,
type BrowserCompleteness,
} from "../browserCompleteness.js";
import {
electronPageInspectionSchema,
type ElectronPageInspection,
} from "./electronObservation.js";
import {
javascriptRuntimeObservationSchema,
javascriptRuntimeKindSchema,
type JavaScriptRuntimeObservation,
type JavaScriptRuntimeTargetLocation,
} from "./javascriptRuntimeObservation.js";
import { digestCanonicalValue } from "../canonicalDigest.js";
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
import { parseEvidence, type Evidence } from "../evidence.js";
import { parseActiveElectronCapture } from "./javascriptRuntimeReconciliationActive.js";
import {
assertEvidenceIdentity,
invalidInput,
parseAtPath,
} from "./javascriptRuntimeReconciliationInputValidation.js";
interface RuntimeCaptureBase {
readonly evidence: Evidence;
readonly captureSha256: string;
readonly scriptsCompleteWithinScope: boolean;
}
interface NormalizedV8Inspection {
readonly target:
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly file_path: string;
}
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly url: string;
}
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly unresolved_location: Extract<
JavaScriptRuntimeObservation["target"]["location"],
{ kind: "unresolved" }
>;
};
readonly frames: readonly [];
readonly scripts: {
readonly items: readonly (Readonly<{
script_key: string;
frame_id: string | null;
cdp_hash: string | null;
length: number | null;
is_module: boolean | null;
language: null;
source: { readonly included: false; readonly reason: string };
}> &
(
| { readonly file_path: string }
| { readonly url: string }
| {
readonly unresolved_location: Extract<
JavaScriptRuntimeObservation["scripts"]["items"][number]["location"],
{ kind: "unresolved" }
>;
}
))[];
};
readonly workers: readonly [];
readonly completeness: BrowserCompleteness;
}
export type ParsedRuntimeCapture =
| (RuntimeCaptureBase & {
readonly kind: "browser";
readonly inspection: WebPageInspection;
})
| (RuntimeCaptureBase & {
readonly kind: "electron";
readonly inspection: ElectronPageInspection;
})
| (RuntimeCaptureBase & {
readonly kind: "v8-inspector";
readonly inspection: NormalizedV8Inspection;
})
| (RuntimeCaptureBase & {
readonly kind: "electron-active";
readonly inspection: {
readonly target: {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly file_path: string;
};
readonly frames: readonly [];
readonly scripts: { readonly items: readonly [] };
readonly workers: readonly [];
readonly completeness: BrowserCompleteness;
};
});
/** Parse only supported passive web/Electron inspection Evidence. */
export const parseRuntimeCaptures = (
observations: readonly Evidence[],
path: readonly (string | number)[] = ["runtime_observations"],
): ParsedRuntimeCapture[] =>
observations
.map((observation, index) =>
parseRuntimeCapture(observation, [...path, index]),
)
.sort((left, right) =>
compareUnicodeCodePoints(
left.evidence.evidence_id,
right.evidence.evidence_id,
),
);
const parseRuntimeCapture = (
input: Evidence,
evidencePath: readonly (string | number)[],
): ParsedRuntimeCapture => {
const evidence = parseAtPath(parseEvidence, input, evidencePath);
if (evidence.operation === "inspect_web_page")
return parseBrowserCapture(evidence, evidencePath);
if (evidence.operation === "inspect_electron_page")
return parseElectronCapture(evidence, evidencePath);
if (evidence.operation === "observe_javascript_runtime")
return parseV8Capture(evidence, evidencePath);
if (evidence.operation === "capture_electron_scenario") {
return parseAtPath(
() => parseActiveElectronCapture(evidence),
evidence,
evidencePath,
);
}
throw invalidInput(
evidencePath,
"Runtime reconciliation requires inspect_web_page, inspect_electron_page, observe_javascript_runtime, or capture_electron_scenario Evidence",
);
};
const parseBrowserCapture = (
evidence: Evidence,
path: readonly (string | number)[],
): ParsedRuntimeCapture => {
assertEvidenceIdentity(
evidence,
{
operation: "inspect_web_page",
predicate: "rea.web-page-inspection",
providerId: "rea-cdp-browser",
providerName: "REA Chrome DevTools Protocol observation provider",
providerVersion: "2",
authority: "external-service",
confidence: "observed",
},
path,
);
const inspection = parseAtPath(
(value) => webPageInspectionSchema.parse(value),
evidence.normalized_result,
[...path, "normalized_result"],
);
assertRuntimeParameters(
evidence,
{
kind: "browser",
targetId: inspection.target.target_id,
targetOrigin: inspection.target.origin,
sourceIncluded: inspection.scripts.items.some(
({ source }) => source.included,
),
},
path,
);
return {
kind: "browser",
evidence,
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
};
};
const parseElectronCapture = (
evidence: Evidence,
path: readonly (string | number)[],
): ParsedRuntimeCapture => {
assertEvidenceIdentity(
evidence,
{
operation: "inspect_electron_page",
predicate: "rea.electron-page-inspection",
providerId: "rea-cdp-electron",
providerName: "REA Electron file-page CDP observation provider",
providerVersion: "1",
authority: "external-service",
confidence: "observed",
},
path,
);
const inspection = parseAtPath(
(value) => electronPageInspectionSchema.parse(value),
evidence.normalized_result,
[...path, "normalized_result"],
);
assertRuntimeParameters(
evidence,
{
kind: "electron",
targetId: inspection.target.target_id,
sourceIncluded: inspection.scripts.items.some(
({ source }) => source.included,
),
},
path,
);
return {
kind: "electron",
evidence,
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
};
};
const parseV8Capture = (
evidence: Evidence,
path: readonly (string | number)[],
): ParsedRuntimeCapture => {
assertEvidenceIdentity(
evidence,
{
operation: "observe_javascript_runtime",
predicate: "rea.javascript-runtime-observation",
providerId: "rea-v8-inspector",
providerName: "REA passive Node/Electron V8 Inspector provider",
providerVersion: "1",
authority: "external-service",
confidence: "observed",
},
path,
);
const result = parseAtPath(
(value) => javascriptRuntimeObservationSchema.parse(value),
evidence.normalized_result,
[...path, "normalized_result"],
);
assertV8RuntimeParameters(evidence, result, path);
return {
kind: "v8-inspector",
evidence,
inspection: normalizeV8Inspection(result),
captureSha256: digestCanonicalValue(result, "Runtime reconciliation"),
scriptsCompleteWithinScope: false,
};
};
const assertV8RuntimeParameters = (
evidence: Evidence,
result: JavaScriptRuntimeObservation,
path: readonly (string | number)[],
): void => {
const parameters = parseAtPath(
(value) =>
z
.object({
inspector_endpoint: browserEndpointSchema,
target_id: z.string().trim().min(1),
runtime_kind: javascriptRuntimeKindSchema.optional(),
})
.passthrough()
.parse(value),
evidence.parameters,
[...path, "parameters"],
);
if (
parameters.target_id !== result.target.target_id ||
(parameters.runtime_kind !== undefined &&
parameters.runtime_kind !== result.target.runtime_kind)
)
throw invalidInput(
[...path, "parameters", "target_id"],
"Runtime Evidence target or declared role disagrees with its result",
);
if (
result.target.location.kind === "builtin" &&
!result.target.location.specifier.startsWith("node:")
)
throw invalidInput(
[...path, "normalized_result", "target", "location"],
"Runtime Evidence contains an invalid builtin location",
);
for (const [index, { location }] of result.scripts.items.entries())
if (location.kind === "builtin" && !location.specifier.startsWith("node:"))
throw invalidInput(
[...path, "normalized_result", "scripts", "items", index, "location"],
"Runtime Evidence contains an invalid builtin location",
);
};
const normalizeV8Inspection = (
result: JavaScriptRuntimeObservation,
): NormalizedV8Inspection => ({
target: {
target_id: result.target.target_id,
type: result.target.protocol_type,
title: result.target.runtime_kind,
attached: result.target.attached,
...(result.target.location.kind === "unresolved"
? { unresolved_location: result.target.location }
: runtimeLocation(result.target.location)),
},
frames: [],
scripts: {
items: result.scripts.items.map((script) => ({
script_key: script.script_key,
frame_id: script.execution_context_key,
...runtimeLocation(script.location),
cdp_hash: script.cdp_hash,
length: script.length,
is_module: script.is_module,
language: null,
source: {
included: false,
reason: "V8 Inspector source capture is outside passive authority.",
},
})),
},
workers: [],
completeness: classifyBrowserCompleteness({
policyFilteredSections: new Set(
excludedV8Scripts(result) > 0 ? ["scripts"] : [],
),
attachLimitedSections: new Set([
"frames",
"scripts",
"script_sources",
"workers",
]),
truncatedSections: new Set(result.capture.truncated ? ["scripts"] : []),
unavailableSections: new Set(["frames", "script_sources", "workers"]),
excluded:
excludedV8Scripts(result) === 0
? []
: [
{
section: "scripts",
reason: "out_of_target_scope",
count: excludedV8Scripts(result),
},
],
droppedEvents: {
scripts: result.capture.events_dropped,
network_requests: 0,
console_events: 0,
websocket_connections: 0,
websocket_frames: 0,
webmcp_tools: 0,
timeline_events: 0,
},
}),
});
const runtimeLocation = (
location: JavaScriptRuntimeTargetLocation,
):
| { readonly file_path: string }
| { readonly url: string }
| {
readonly unresolved_location: Extract<
JavaScriptRuntimeTargetLocation,
{ kind: "unresolved" }
>;
} => {
if (location.kind === "unresolved") return { unresolved_location: location };
if (location.kind === "file") return { file_path: location.file_path };
if (location.kind === "url") return { url: location.sanitized_url };
return { url: location.specifier };
};
const excludedV8Scripts = (result: JavaScriptRuntimeObservation): number =>
Object.values(result.scripts.excluded).reduce(
(total, count) => total + count,
0,
);
const assertRuntimeParameters = (
evidence: Evidence,
expected:
| {
readonly kind: "browser";
readonly targetId: string;
readonly targetOrigin: string;
readonly sourceIncluded: boolean;
}
| {
readonly kind: "electron";
readonly targetId: string;
readonly sourceIncluded: boolean;
},
path: readonly (string | number)[],
): void => {
const common = {
target_id: z.string().trim().min(1),
cdp_endpoint: browserEndpointSchema,
include_script_sources: z.boolean(),
};
if (expected.kind === "browser") {
const parameters = parseAtPath(
(value) =>
z
.object({ ...common, allowed_origins: browserAllowedOriginsSchema })
.passthrough()
.parse(value),
evidence.parameters,
[...path, "parameters"],
);
if (parameters.target_id !== expected.targetId)
throw invalidInput(
[...path, "parameters", "target_id"],
"Runtime Evidence target disagrees with its captured result",
);
if (!parameters.allowed_origins.includes(expected.targetOrigin))
throw invalidInput(
[...path, "parameters", "allowed_origins"],
"Browser Evidence target is outside its recorded origin scope",
);
if (expected.sourceIncluded && !parameters.include_script_sources)
throw invalidInput(
[...path, "parameters", "include_script_sources"],
"Runtime Evidence contains source without source-capture selection",
);
return;
}
const parameters = parseAtPath(
(value) => z.object(common).passthrough().parse(value),
evidence.parameters,
[...path, "parameters"],
);
if (parameters.target_id !== expected.targetId)
throw invalidInput(
[...path, "parameters", "target_id"],
"Runtime Evidence target disagrees with its captured result",
);
if (expected.sourceIncluded && !parameters.include_script_sources)
throw invalidInput(
[...path, "parameters", "include_script_sources"],
"Runtime Evidence contains source without source-capture selection",
);
};
const scriptsComplete = (completeness: {
readonly truncated_sections: readonly string[];
readonly unavailable_sections: readonly string[];
readonly dropped_events: { readonly scripts: number };
}): boolean =>
!completeness.truncated_sections.includes("scripts") &&
!completeness.unavailable_sections.includes("scripts") &&
completeness.dropped_events.scripts === 0;
@@ -7,10 +7,8 @@ import type {
ApplicationEdge,
ApplicationNode,
} from "./javascriptApplicationGraphSchemas.js";
import type {
ParsedRuntimeCapture,
ParsedStaticLayer,
} from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedStaticLayer } from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationCaptureParsing.js";
import { uniqueSorted } from "../canonicalOrdering.js";
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
import type { RuntimeProjection } from "./javascriptRuntimeReconciliationRuntime.js";
@@ -0,0 +1,57 @@
import { z } from "zod";
import type { Evidence } from "../evidence.js";
/** Prefix caller paths on a nested Zod validation boundary. */
export const parseAtPath = <Value>(
parse: (input: unknown) => Value,
input: unknown,
path: readonly (string | number)[],
): Value => {
try {
return parse(input);
} catch (cause: unknown) {
if (cause instanceof z.ZodError)
throw new z.ZodError(
cause.issues.map((issue) => ({
...issue,
path: [...path, ...issue.path],
})),
);
throw cause;
}
};
/** Represent one semantic caller constraint as a standard validation issue. */
export const invalidInput = (
path: readonly (string | number)[],
message: string,
): z.ZodError => new z.ZodError([{ code: "custom", path: [...path], message }]);
/** Verify an authenticated Evidence record against one runtime workflow. */
export const assertEvidenceIdentity = (
evidence: Evidence,
expected: {
readonly operation: string;
readonly predicate: string;
readonly providerId: string;
readonly providerName: string;
readonly providerVersion: string;
readonly authority: Evidence["authority"];
readonly confidence: Evidence["confidence"];
},
path: readonly (string | number)[],
): void => {
if (
evidence.operation !== expected.operation ||
evidence.predicate_type !== expected.predicate ||
evidence.provider.id !== expected.providerId ||
evidence.provider.name !== expected.providerName ||
evidence.provider.version !== expected.providerVersion ||
evidence.authority !== expected.authority ||
evidence.confidence !== expected.confidence
)
throw invalidInput(
path,
`Evidence does not match the supported ${expected.operation} contract`,
);
};
@@ -1,27 +1,3 @@
import { z } from "zod";
import {
browserAllowedOriginsSchema,
browserEndpointSchema,
} from "../browserObservation.js";
import {
webPageInspectionSchema,
type WebPageInspection,
} from "../browserObservationSchemas.js";
import {
classifyBrowserCompleteness,
type BrowserCompleteness,
} from "../browserCompleteness.js";
import {
electronPageInspectionSchema,
type ElectronPageInspection,
} from "./electronObservation.js";
import {
javascriptRuntimeObservationSchema,
javascriptRuntimeKindSchema,
type JavaScriptRuntimeObservation,
type JavaScriptRuntimeTargetLocation,
} from "./javascriptRuntimeObservation.js";
import { digestCanonicalValue } from "../canonicalDigest.js";
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
import { parseEvidence, type Evidence } from "../evidence.js";
@@ -29,9 +5,13 @@ import {
javascriptApplicationAnalysisResultSchema,
type JavaScriptApplicationAnalysisResult,
} from "./javascriptApplicationAnalysis.js";
import { type JavaScriptApplicationGraph } from "./javascriptApplicationGraph.js";
import { parseActiveElectronCapture } from "./javascriptRuntimeReconciliationActive.js";
import type { JavaScriptApplicationGraph } from "./javascriptApplicationGraph.js";
import type { ReconcileJavaScriptRuntimeInput } from "./javascriptRuntimeReconciliationSchemas.js";
import {
assertEvidenceIdentity,
invalidInput,
parseAtPath,
} from "./javascriptRuntimeReconciliationInputValidation.js";
type StaticLayerInput =
ReconcileJavaScriptRuntimeInput["static_layers"][number];
@@ -46,138 +26,50 @@ export interface ParsedStaticLayer {
readonly runtimeMappings: readonly RuntimeMapping[];
}
interface RuntimeCaptureBase {
readonly evidence: Evidence;
readonly captureSha256: string;
readonly scriptsCompleteWithinScope: boolean;
}
interface NormalizedV8Inspection {
readonly target:
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly file_path: string;
}
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly url: string;
}
| {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly unresolved_location: Extract<
JavaScriptRuntimeObservation["target"]["location"],
{ kind: "unresolved" }
>;
};
readonly frames: readonly [];
readonly scripts: {
readonly items: readonly (Readonly<{
script_key: string;
frame_id: string | null;
cdp_hash: string | null;
length: number | null;
is_module: boolean | null;
language: null;
source: { readonly included: false; readonly reason: string };
}> &
(
| { readonly file_path: string }
| { readonly url: string }
| {
readonly unresolved_location: Extract<
JavaScriptRuntimeObservation["scripts"]["items"][number]["location"],
{ kind: "unresolved" }
>;
}
))[];
};
readonly workers: readonly [];
readonly completeness: BrowserCompleteness;
}
export type ParsedRuntimeCapture =
| (RuntimeCaptureBase & {
readonly kind: "browser";
readonly inspection: WebPageInspection;
})
| (RuntimeCaptureBase & {
readonly kind: "electron";
readonly inspection: ElectronPageInspection;
})
| (RuntimeCaptureBase & {
readonly kind: "v8-inspector";
readonly inspection: NormalizedV8Inspection;
})
| (RuntimeCaptureBase & {
readonly kind: "electron-active";
readonly inspection: {
readonly target: {
readonly target_id: string;
readonly type: string;
readonly title: string;
readonly attached: boolean;
readonly file_path: string;
};
readonly frames: readonly [];
readonly scripts: { readonly items: readonly [] };
readonly workers: readonly [];
readonly completeness: BrowserCompleteness;
};
});
/** Parse and semantically bind every static analysis Evidence layer. */
export const parseStaticLayers = (
layers: readonly StaticLayerInput[],
path: readonly (string | number)[] = ["static_layers"],
): ParsedStaticLayer[] =>
layers
.map((layer) => parseStaticLayer(layer))
.map((layer, index) =>
parseStaticLayer(layer, [...path, index, "analysis"]),
)
.sort((left, right) =>
compareUnicodeCodePoints(left.layerId, right.layerId),
);
/** Parse only supported passive web/Electron inspection Evidence. */
export const parseRuntimeCaptures = (
observations: readonly Evidence[],
): ParsedRuntimeCapture[] =>
observations
.map((observation) => parseRuntimeCapture(observation))
.sort((left, right) =>
compareUnicodeCodePoints(
left.evidence.evidence_id,
right.evidence.evidence_id,
),
);
const parseStaticLayer = (layer: StaticLayerInput): ParsedStaticLayer => {
const evidence = parseEvidence(layer.analysis);
const result = javascriptApplicationAnalysisResultSchema.parse(
const parseStaticLayer = (
layer: StaticLayerInput,
evidencePath: readonly (string | number)[],
): ParsedStaticLayer => {
const evidence = parseAtPath(parseEvidence, layer.analysis, evidencePath);
const result = parseAtPath(
(value) => javascriptApplicationAnalysisResultSchema.parse(value),
evidence.normalized_result,
[...evidencePath, "normalized_result"],
);
assertEvidenceIdentity(
evidence,
{
operation: "analyze_javascript_application",
predicate: "rea.javascript-application-analysis",
providerId: "rea-javascript-application",
providerName: "REA JavaScript application analyzer",
providerVersion: "1",
authority: "shipped-artifact",
confidence: "derived",
},
evidencePath,
);
assertEvidenceIdentity(evidence, {
operation: "analyze_javascript_application",
predicate: "rea.javascript-application-analysis",
providerId: "rea-javascript-application",
providerName: "REA JavaScript application analyzer",
providerVersion: "1",
authority: "shipped-artifact",
confidence: "derived",
});
if (
evidence.subject === null ||
evidence.subject.digest.sha256 !== result.root_artifact_sha256 ||
evidence.subject.format !== result.format ||
evidence.subject.local_path !== result.input_path
)
throw new TypeError(
throw invalidInput(
[...evidencePath, "subject"],
"JavaScript application Evidence subject disagrees with its result",
);
return {
@@ -196,294 +88,3 @@ const parseStaticLayer = (layer: StaticLayerInput): ParsedStaticLayer => {
runtimeMappings: layer.runtime_mappings,
};
};
const parseRuntimeCapture = (input: Evidence): ParsedRuntimeCapture => {
const evidence = parseEvidence(input);
if (evidence.operation === "inspect_web_page") {
assertEvidenceIdentity(evidence, {
operation: "inspect_web_page",
predicate: "rea.web-page-inspection",
providerId: "rea-cdp-browser",
providerName: "REA Chrome DevTools Protocol observation provider",
providerVersion: "2",
authority: "external-service",
confidence: "observed",
});
const inspection = webPageInspectionSchema.parse(
evidence.normalized_result,
);
assertRuntimeParameters(evidence, {
kind: "browser",
targetId: inspection.target.target_id,
targetOrigin: inspection.target.origin,
sourceIncluded: inspection.scripts.items.some(
({ source }) => source.included,
),
});
return {
kind: "browser",
evidence,
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
};
}
if (evidence.operation === "inspect_electron_page") {
assertEvidenceIdentity(evidence, {
operation: "inspect_electron_page",
predicate: "rea.electron-page-inspection",
providerId: "rea-cdp-electron",
providerName: "REA Electron file-page CDP observation provider",
providerVersion: "1",
authority: "external-service",
confidence: "observed",
});
const inspection = electronPageInspectionSchema.parse(
evidence.normalized_result,
);
assertRuntimeParameters(evidence, {
kind: "electron",
targetId: inspection.target.target_id,
sourceIncluded: inspection.scripts.items.some(
({ source }) => source.included,
),
});
return {
kind: "electron",
evidence,
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
};
}
if (evidence.operation === "observe_javascript_runtime") {
assertEvidenceIdentity(evidence, {
operation: "observe_javascript_runtime",
predicate: "rea.javascript-runtime-observation",
providerId: "rea-v8-inspector",
providerName: "REA passive Node/Electron V8 Inspector provider",
providerVersion: "1",
authority: "external-service",
confidence: "observed",
});
const result = javascriptRuntimeObservationSchema.parse(
evidence.normalized_result,
);
assertV8RuntimeParameters(evidence, result);
const inspection = normalizeV8Inspection(result);
return {
kind: "v8-inspector",
evidence,
inspection,
captureSha256: digestCanonicalValue(result, "Runtime reconciliation"),
scriptsCompleteWithinScope: false,
};
}
if (evidence.operation === "capture_electron_scenario") {
return parseActiveElectronCapture(evidence);
}
throw new TypeError(
"Runtime reconciliation requires inspect_web_page, inspect_electron_page, observe_javascript_runtime, or capture_electron_scenario Evidence",
);
};
const assertV8RuntimeParameters = (
evidence: Evidence,
result: JavaScriptRuntimeObservation,
): void => {
const parameters = z
.object({
inspector_endpoint: browserEndpointSchema,
target_id: z.string().trim().min(1),
runtime_kind: javascriptRuntimeKindSchema.optional(),
})
.passthrough()
.parse(evidence.parameters);
if (
parameters.target_id !== result.target.target_id ||
(parameters.runtime_kind !== undefined &&
parameters.runtime_kind !== result.target.runtime_kind)
)
throw new TypeError(
"Runtime Evidence target or declared role disagrees with its result",
);
for (const location of [
result.target.location,
...result.scripts.items.map(({ location }) => location),
])
if (location.kind === "builtin" && !location.specifier.startsWith("node:"))
throw new TypeError(
"Runtime Evidence contains an invalid builtin location",
);
};
const normalizeV8Inspection = (
result: JavaScriptRuntimeObservation,
): NormalizedV8Inspection => ({
target: {
target_id: result.target.target_id,
type: result.target.protocol_type,
title: result.target.runtime_kind,
attached: result.target.attached,
...(result.target.location.kind === "unresolved"
? { unresolved_location: result.target.location }
: runtimeLocation(result.target.location)),
},
frames: [],
scripts: {
items: result.scripts.items.map((script) => ({
script_key: script.script_key,
frame_id: script.execution_context_key,
...runtimeLocation(script.location),
cdp_hash: script.cdp_hash,
length: script.length,
is_module: script.is_module,
language: null,
source: {
included: false,
reason: "V8 Inspector source capture is outside passive authority.",
},
})),
},
workers: [],
completeness: classifyBrowserCompleteness({
policyFilteredSections: new Set(
excludedV8Scripts(result) > 0 ? ["scripts"] : [],
),
attachLimitedSections: new Set([
"frames",
"scripts",
"script_sources",
"workers",
]),
truncatedSections: new Set(result.capture.truncated ? ["scripts"] : []),
unavailableSections: new Set(["frames", "script_sources", "workers"]),
excluded:
excludedV8Scripts(result) === 0
? []
: [
{
section: "scripts",
reason: "out_of_target_scope",
count: excludedV8Scripts(result),
},
],
droppedEvents: {
scripts: result.capture.events_dropped,
network_requests: 0,
console_events: 0,
websocket_connections: 0,
websocket_frames: 0,
webmcp_tools: 0,
timeline_events: 0,
},
}),
});
const runtimeLocation = (
location: JavaScriptRuntimeTargetLocation,
):
| { readonly file_path: string }
| { readonly url: string }
| {
readonly unresolved_location: Extract<
JavaScriptRuntimeTargetLocation,
{ kind: "unresolved" }
>;
} => {
if (location.kind === "unresolved") return { unresolved_location: location };
if (location.kind === "file") return { file_path: location.file_path };
if (location.kind === "url") return { url: location.sanitized_url };
return { url: location.specifier };
};
const excludedV8Scripts = (result: JavaScriptRuntimeObservation): number =>
Object.values(result.scripts.excluded).reduce(
(total, count) => total + count,
0,
);
const assertRuntimeParameters = (
evidence: Evidence,
expected:
| {
readonly kind: "browser";
readonly targetId: string;
readonly targetOrigin: string;
readonly sourceIncluded: boolean;
}
| {
readonly kind: "electron";
readonly targetId: string;
readonly sourceIncluded: boolean;
},
): void => {
const common = {
target_id: z.string().trim().min(1),
cdp_endpoint: browserEndpointSchema,
include_script_sources: z.boolean(),
};
if (expected.kind === "browser") {
const parameters = z
.object({ ...common, allowed_origins: browserAllowedOriginsSchema })
.passthrough()
.parse(evidence.parameters);
if (parameters.target_id !== expected.targetId)
throw new TypeError(
"Runtime Evidence target disagrees with its captured result",
);
if (!parameters.allowed_origins.includes(expected.targetOrigin))
throw new TypeError(
"Browser Evidence target is outside its recorded origin scope",
);
if (expected.sourceIncluded && !parameters.include_script_sources)
throw new TypeError(
"Runtime Evidence contains source without source-capture selection",
);
return;
}
const parameters = z.object(common).passthrough().parse(evidence.parameters);
if (parameters.target_id !== expected.targetId)
throw new TypeError(
"Runtime Evidence target disagrees with its captured result",
);
if (expected.sourceIncluded && !parameters.include_script_sources)
throw new TypeError(
"Runtime Evidence contains source without source-capture selection",
);
};
const scriptsComplete = (completeness: {
readonly truncated_sections: readonly string[];
readonly unavailable_sections: readonly string[];
readonly dropped_events: { readonly scripts: number };
}): boolean =>
!completeness.truncated_sections.includes("scripts") &&
!completeness.unavailable_sections.includes("scripts") &&
completeness.dropped_events.scripts === 0;
const assertEvidenceIdentity = (
evidence: Evidence,
expected: {
readonly operation: string;
readonly predicate: string;
readonly providerId: string;
readonly providerName: string;
readonly providerVersion: string;
readonly authority: Evidence["authority"];
readonly confidence: Evidence["confidence"];
},
): void => {
if (
evidence.operation !== expected.operation ||
evidence.predicate_type !== expected.predicate ||
evidence.provider.id !== expected.providerId ||
evidence.provider.name !== expected.providerName ||
evidence.provider.version !== expected.providerVersion ||
evidence.authority !== expected.authority ||
evidence.confidence !== expected.confidence
)
throw new TypeError(
`Evidence does not match the supported ${expected.operation} contract`,
);
};
@@ -3,10 +3,8 @@ import { digestCanonicalValue } from "../canonicalDigest.js";
import { uniqueSorted } from "../canonicalOrdering.js";
import type { StaticLoadStateProjection } from "./javascriptRuntimeLoadState.js";
import type { RuntimeMatchingProjection } from "./javascriptRuntimeReconciliationMatching.js";
import type {
ParsedRuntimeCapture,
ParsedStaticLayer,
} from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedStaticLayer } from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationCaptureParsing.js";
import {
javascriptRuntimeReconciliationResultSchema,
type JavaScriptRuntimeReconciliationResult,
@@ -8,7 +8,7 @@ import type {
ApplicationNode,
} from "./javascriptApplicationGraphSchemas.js";
import type { ApplicationGraphEvidence } from "./javascriptApplicationEvidenceSchemas.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationParsing.js";
import type { ParsedRuntimeCapture } from "./javascriptRuntimeReconciliationCaptureParsing.js";
export interface RuntimeReconciliationEntity {
readonly kind: "target" | "frame" | "script" | "worker";