rea-agents 6.2.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -20
- package/bridge/hopper_bridge.py +2 -0
- package/dist/android/JadxProvider.js +8 -2
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +63 -17
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/ClientConfigurationDocument.js +28 -0
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +12 -6
- package/dist/application/DirectAnalysisCleanup.js +0 -1
- package/dist/application/DirectAnalysisStatus.js +2 -5
- package/dist/application/Doctor.js +25 -34
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/InvestigationProviders.js +4 -4
- package/dist/application/JsonFiles.js +15 -15
- package/dist/application/LinuxHopper.js +2 -1
- package/dist/application/ReconstructionObligationCandidates.js +9 -2
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +18 -7
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +6 -4
- package/dist/application/SetupPlan.js +19 -15
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +18 -2
- package/dist/application/UpdateMaintenance.js +6 -2
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +13 -6
- package/dist/application/android/AndroidAnalysisService.js +1 -1
- package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
- package/dist/application/binary/BinarySession.js +16 -0
- package/dist/application/binary/BinarySessionOpen.js +9 -1
- package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/artifacts/ArtifactProvider.js +14 -16
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/scanCanonical.js +28 -22
- package/dist/artifacts/inventory/scanReader.js +7 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/CdpBrowserProvider.js +4 -3
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -3
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
- package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
- package/dist/browser/PlaywrightScenarioSession.js +3 -11
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +13 -9
- package/dist/cli/electronCommands.js +9 -10
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- package/dist/cli/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +2 -4
- package/dist/cli.js +5 -2
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +47 -34
- package/dist/cliObservationOptions.js +4 -0
- package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
- package/dist/composition/browserScenario.js +2 -2
- package/dist/composition/directAnalysis.js +2 -3
- package/dist/contracts/artifactComparisonExample.js +5 -5
- package/dist/contracts/errorSchemas.js +3 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/inputSchemaPresentation.js +94 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -1
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +3 -2
- package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
- package/dist/contracts/native/nativeToolContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +3 -2
- package/dist/contracts/sessionToolSchemas.js +3 -2
- package/dist/contracts/toolOutputSchemaGroups.js +2 -2
- package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
- package/dist/domain/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorPresentation.js +4 -2
- package/dist/domain/analysisSnapshot.js +3 -1
- package/dist/domain/analysisView/analysisView.js +1 -3
- package/dist/domain/android/androidPartialObservation.js +36 -0
- package/dist/domain/apple/dylibResolution.js +1 -1
- package/dist/domain/artifactComparison.js +4 -4
- package/dist/domain/artifactGraph.js +1 -1
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- package/dist/domain/artifactInventoryEvidence.js +5 -5
- package/dist/domain/browserCompleteness.js +3 -2
- package/dist/domain/browserScenarioCaptureValues.js +2 -2
- package/dist/domain/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +3 -2
- package/dist/domain/callPath.js +8 -10
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +10 -5
- package/dist/domain/evidenceBundle.js +51 -33
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +2 -1
- package/dist/domain/functionComparisonNormalization.js +4 -3
- package/dist/domain/functionComparisonResults.js +2 -2
- package/dist/domain/functionDossierEvidence.js +2 -1
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +4 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
- package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
- package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
- package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
- package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
- package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
- package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
- package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
- package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- package/dist/domain/native/nativeCallObservation.js +2 -4
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/process/processCapture.js +11 -10
- package/dist/domain/process/processCaptureCoverage.js +8 -5
- package/dist/domain/process/processCaptureExample.js +43 -0
- package/dist/domain/process/processCaptureValidation.js +4 -3
- package/dist/domain/process/processComparison.js +0 -23
- package/dist/domain/process/processScenario.js +3 -3
- package/dist/domain/process/processTraceEvaluation.js +4 -4
- package/dist/domain/process/processTraceSpecification.js +1 -3
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +3 -2
- package/dist/domain/referenceSourceGraph.js +7 -7
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +2 -1
- package/dist/domain/swiftSymbolClassification.js +6 -1
- package/dist/domain/symbolAnalysis.js +17 -2
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -29
- package/dist/domain/webCaptureDiffSchemas.js +2 -8
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- package/dist/dotnet/ManagedStaticProvider.js +10 -7
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- package/dist/filesystem/RegularFile.js +41 -0
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraClient.js +14 -4
- package/dist/ghidra/GhidraInstallation.js +111 -10
- package/dist/ghidra/GhidraLauncher.js +43 -19
- package/dist/hopper/HopperCleanup.js +1 -1
- package/dist/ida/IdaOperationRunner.js +2 -0
- package/dist/ida/IdaSessionClient.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
- package/dist/inspector/V8InspectorProvider.js +60 -8
- package/dist/main/shutdown.js +76 -32
- package/dist/main/transport.js +1 -1
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/LldbCallTracer.js +241 -75
- package/dist/native/NativeMacOSProvider.js +10 -5
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- package/dist/process/ProcessOwnershipObservation.js +9 -13
- package/dist/process/capture/FilesystemSnapshot.js +88 -18
- package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
- package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
- package/dist/process/capture/ProcessHarness.js +8 -21
- package/dist/server/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +22 -23
- package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
- package/dist/server/registerApplicationTools/helpers.js +3 -2
- package/dist/server/registerArtifactTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +6 -4
- package/dist/server/registerEnhancedTools.js +78 -73
- package/dist/server/registerEvidenceTools.js +54 -46
- package/dist/server/registerManagedTools.js +7 -4
- package/dist/server/registerOfficialTools.js +31 -25
- package/dist/server/registerSessionTools.js +9 -3
- package/native/windows/build/manifest.json +1 -1
- package/package.json +6 -3
- package/skills/reverse-engineer-anything/SKILL.md +5 -5
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/server/registerNativeTools.js +0 -6
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { browserAllowedOriginsSchema, browserEndpointSchema, } from "../browserObservation.js";
|
|
3
|
+
import { webPageInspectionSchema, } from "../browserObservationSchemas.js";
|
|
4
|
+
import { classifyBrowserCompleteness, } from "../browserCompleteness.js";
|
|
5
|
+
import { electronPageInspectionSchema, } from "./electronObservation.js";
|
|
6
|
+
import { javascriptRuntimeObservationSchema, javascriptRuntimeKindSchema, } from "./javascriptRuntimeObservation.js";
|
|
7
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
8
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
9
|
+
import { parseEvidence } from "../evidence.js";
|
|
10
|
+
import { parseActiveElectronCapture } from "./javascriptRuntimeReconciliationActive.js";
|
|
11
|
+
import { assertEvidenceIdentity, invalidInput, parseAtPath, } from "./javascriptRuntimeReconciliationInputValidation.js";
|
|
12
|
+
/** Parse only supported passive web/Electron inspection Evidence. */
|
|
13
|
+
export const parseRuntimeCaptures = (observations, path = ["runtime_observations"]) => observations
|
|
14
|
+
.map((observation, index) => parseRuntimeCapture(observation, [...path, index]))
|
|
15
|
+
.sort((left, right) => compareUnicodeCodePoints(left.evidence.evidence_id, right.evidence.evidence_id));
|
|
16
|
+
const parseRuntimeCapture = (input, evidencePath) => {
|
|
17
|
+
const evidence = parseAtPath(parseEvidence, input, evidencePath);
|
|
18
|
+
if (evidence.operation === "inspect_web_page")
|
|
19
|
+
return parseBrowserCapture(evidence, evidencePath);
|
|
20
|
+
if (evidence.operation === "inspect_electron_page")
|
|
21
|
+
return parseElectronCapture(evidence, evidencePath);
|
|
22
|
+
if (evidence.operation === "observe_javascript_runtime")
|
|
23
|
+
return parseV8Capture(evidence, evidencePath);
|
|
24
|
+
if (evidence.operation === "capture_electron_scenario") {
|
|
25
|
+
return parseAtPath(() => parseActiveElectronCapture(evidence), evidence, evidencePath);
|
|
26
|
+
}
|
|
27
|
+
throw invalidInput(evidencePath, "Runtime reconciliation requires inspect_web_page, inspect_electron_page, observe_javascript_runtime, or capture_electron_scenario Evidence");
|
|
28
|
+
};
|
|
29
|
+
const parseBrowserCapture = (evidence, path) => {
|
|
30
|
+
assertEvidenceIdentity(evidence, {
|
|
31
|
+
operation: "inspect_web_page",
|
|
32
|
+
predicate: "rea.web-page-inspection",
|
|
33
|
+
providerId: "rea-cdp-browser",
|
|
34
|
+
providerName: "REA Chrome DevTools Protocol observation provider",
|
|
35
|
+
providerVersion: "2",
|
|
36
|
+
authority: "external-service",
|
|
37
|
+
confidence: "observed",
|
|
38
|
+
}, path);
|
|
39
|
+
const inspection = parseAtPath((value) => webPageInspectionSchema.parse(value), evidence.normalized_result, [...path, "normalized_result"]);
|
|
40
|
+
assertRuntimeParameters(evidence, {
|
|
41
|
+
kind: "browser",
|
|
42
|
+
targetId: inspection.target.target_id,
|
|
43
|
+
targetOrigin: inspection.target.origin,
|
|
44
|
+
sourceIncluded: inspection.scripts.items.some(({ source }) => source.included),
|
|
45
|
+
}, path);
|
|
46
|
+
return {
|
|
47
|
+
kind: "browser",
|
|
48
|
+
evidence,
|
|
49
|
+
inspection,
|
|
50
|
+
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
|
|
51
|
+
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const parseElectronCapture = (evidence, path) => {
|
|
55
|
+
assertEvidenceIdentity(evidence, {
|
|
56
|
+
operation: "inspect_electron_page",
|
|
57
|
+
predicate: "rea.electron-page-inspection",
|
|
58
|
+
providerId: "rea-cdp-electron",
|
|
59
|
+
providerName: "REA Electron file-page CDP observation provider",
|
|
60
|
+
providerVersion: "1",
|
|
61
|
+
authority: "external-service",
|
|
62
|
+
confidence: "observed",
|
|
63
|
+
}, path);
|
|
64
|
+
const inspection = parseAtPath((value) => electronPageInspectionSchema.parse(value), evidence.normalized_result, [...path, "normalized_result"]);
|
|
65
|
+
assertRuntimeParameters(evidence, {
|
|
66
|
+
kind: "electron",
|
|
67
|
+
targetId: inspection.target.target_id,
|
|
68
|
+
sourceIncluded: inspection.scripts.items.some(({ source }) => source.included),
|
|
69
|
+
}, path);
|
|
70
|
+
return {
|
|
71
|
+
kind: "electron",
|
|
72
|
+
evidence,
|
|
73
|
+
inspection,
|
|
74
|
+
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
|
|
75
|
+
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const parseV8Capture = (evidence, path) => {
|
|
79
|
+
assertEvidenceIdentity(evidence, {
|
|
80
|
+
operation: "observe_javascript_runtime",
|
|
81
|
+
predicate: "rea.javascript-runtime-observation",
|
|
82
|
+
providerId: "rea-v8-inspector",
|
|
83
|
+
providerName: "REA passive Node/Electron V8 Inspector provider",
|
|
84
|
+
providerVersion: "1",
|
|
85
|
+
authority: "external-service",
|
|
86
|
+
confidence: "observed",
|
|
87
|
+
}, path);
|
|
88
|
+
const result = parseAtPath((value) => javascriptRuntimeObservationSchema.parse(value), evidence.normalized_result, [...path, "normalized_result"]);
|
|
89
|
+
assertV8RuntimeParameters(evidence, result, path);
|
|
90
|
+
return {
|
|
91
|
+
kind: "v8-inspector",
|
|
92
|
+
evidence,
|
|
93
|
+
inspection: normalizeV8Inspection(result),
|
|
94
|
+
captureSha256: digestCanonicalValue(result, "Runtime reconciliation"),
|
|
95
|
+
scriptsCompleteWithinScope: false,
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
const assertV8RuntimeParameters = (evidence, result, path) => {
|
|
99
|
+
const parameters = parseAtPath((value) => z
|
|
100
|
+
.object({
|
|
101
|
+
inspector_endpoint: browserEndpointSchema,
|
|
102
|
+
target_id: z.string().trim().min(1),
|
|
103
|
+
runtime_kind: javascriptRuntimeKindSchema.optional(),
|
|
104
|
+
})
|
|
105
|
+
.passthrough()
|
|
106
|
+
.parse(value), evidence.parameters, [...path, "parameters"]);
|
|
107
|
+
if (parameters.target_id !== result.target.target_id ||
|
|
108
|
+
(parameters.runtime_kind !== undefined &&
|
|
109
|
+
parameters.runtime_kind !== result.target.runtime_kind))
|
|
110
|
+
throw invalidInput([...path, "parameters", "target_id"], "Runtime Evidence target or declared role disagrees with its result");
|
|
111
|
+
if (result.target.location.kind === "builtin" &&
|
|
112
|
+
!result.target.location.specifier.startsWith("node:"))
|
|
113
|
+
throw invalidInput([...path, "normalized_result", "target", "location"], "Runtime Evidence contains an invalid builtin location");
|
|
114
|
+
for (const [index, { location }] of result.scripts.items.entries())
|
|
115
|
+
if (location.kind === "builtin" && !location.specifier.startsWith("node:"))
|
|
116
|
+
throw invalidInput([...path, "normalized_result", "scripts", "items", index, "location"], "Runtime Evidence contains an invalid builtin location");
|
|
117
|
+
};
|
|
118
|
+
const normalizeV8Inspection = (result) => ({
|
|
119
|
+
target: {
|
|
120
|
+
target_id: result.target.target_id,
|
|
121
|
+
type: result.target.protocol_type,
|
|
122
|
+
title: result.target.runtime_kind,
|
|
123
|
+
attached: result.target.attached,
|
|
124
|
+
...(result.target.location.kind === "unresolved"
|
|
125
|
+
? { unresolved_location: result.target.location }
|
|
126
|
+
: runtimeLocation(result.target.location)),
|
|
127
|
+
},
|
|
128
|
+
frames: [],
|
|
129
|
+
scripts: {
|
|
130
|
+
items: result.scripts.items.map((script) => ({
|
|
131
|
+
script_key: script.script_key,
|
|
132
|
+
frame_id: script.execution_context_key,
|
|
133
|
+
...runtimeLocation(script.location),
|
|
134
|
+
cdp_hash: script.cdp_hash,
|
|
135
|
+
length: script.length,
|
|
136
|
+
is_module: script.is_module,
|
|
137
|
+
language: null,
|
|
138
|
+
source: {
|
|
139
|
+
included: false,
|
|
140
|
+
reason: "V8 Inspector source capture is outside passive authority.",
|
|
141
|
+
},
|
|
142
|
+
})),
|
|
143
|
+
},
|
|
144
|
+
workers: [],
|
|
145
|
+
completeness: classifyBrowserCompleteness({
|
|
146
|
+
policyFilteredSections: new Set(excludedV8Scripts(result) > 0 ? ["scripts"] : []),
|
|
147
|
+
attachLimitedSections: new Set([
|
|
148
|
+
"frames",
|
|
149
|
+
"scripts",
|
|
150
|
+
"script_sources",
|
|
151
|
+
"workers",
|
|
152
|
+
]),
|
|
153
|
+
truncatedSections: new Set(result.capture.truncated ? ["scripts"] : []),
|
|
154
|
+
unavailableSections: new Set(["frames", "script_sources", "workers"]),
|
|
155
|
+
excluded: excludedV8Scripts(result) === 0
|
|
156
|
+
? []
|
|
157
|
+
: [
|
|
158
|
+
{
|
|
159
|
+
section: "scripts",
|
|
160
|
+
reason: "out_of_target_scope",
|
|
161
|
+
count: excludedV8Scripts(result),
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
droppedEvents: {
|
|
165
|
+
scripts: result.capture.events_dropped,
|
|
166
|
+
network_requests: 0,
|
|
167
|
+
console_events: 0,
|
|
168
|
+
websocket_connections: 0,
|
|
169
|
+
websocket_frames: 0,
|
|
170
|
+
webmcp_tools: 0,
|
|
171
|
+
timeline_events: 0,
|
|
172
|
+
},
|
|
173
|
+
}),
|
|
174
|
+
});
|
|
175
|
+
const runtimeLocation = (location) => {
|
|
176
|
+
if (location.kind === "unresolved")
|
|
177
|
+
return { unresolved_location: location };
|
|
178
|
+
if (location.kind === "file")
|
|
179
|
+
return { file_path: location.file_path };
|
|
180
|
+
if (location.kind === "url")
|
|
181
|
+
return { url: location.sanitized_url };
|
|
182
|
+
return { url: location.specifier };
|
|
183
|
+
};
|
|
184
|
+
const excludedV8Scripts = (result) => Object.values(result.scripts.excluded).reduce((total, count) => total + count, 0);
|
|
185
|
+
const assertRuntimeParameters = (evidence, expected, path) => {
|
|
186
|
+
const common = {
|
|
187
|
+
target_id: z.string().trim().min(1),
|
|
188
|
+
cdp_endpoint: browserEndpointSchema,
|
|
189
|
+
include_script_sources: z.boolean(),
|
|
190
|
+
};
|
|
191
|
+
if (expected.kind === "browser") {
|
|
192
|
+
const parameters = parseAtPath((value) => z
|
|
193
|
+
.object({ ...common, allowed_origins: browserAllowedOriginsSchema })
|
|
194
|
+
.passthrough()
|
|
195
|
+
.parse(value), evidence.parameters, [...path, "parameters"]);
|
|
196
|
+
if (parameters.target_id !== expected.targetId)
|
|
197
|
+
throw invalidInput([...path, "parameters", "target_id"], "Runtime Evidence target disagrees with its captured result");
|
|
198
|
+
if (!parameters.allowed_origins.includes(expected.targetOrigin))
|
|
199
|
+
throw invalidInput([...path, "parameters", "allowed_origins"], "Browser Evidence target is outside its recorded origin scope");
|
|
200
|
+
if (expected.sourceIncluded && !parameters.include_script_sources)
|
|
201
|
+
throw invalidInput([...path, "parameters", "include_script_sources"], "Runtime Evidence contains source without source-capture selection");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const parameters = parseAtPath((value) => z.object(common).passthrough().parse(value), evidence.parameters, [...path, "parameters"]);
|
|
205
|
+
if (parameters.target_id !== expected.targetId)
|
|
206
|
+
throw invalidInput([...path, "parameters", "target_id"], "Runtime Evidence target disagrees with its captured result");
|
|
207
|
+
if (expected.sourceIncluded && !parameters.include_script_sources)
|
|
208
|
+
throw invalidInput([...path, "parameters", "include_script_sources"], "Runtime Evidence contains source without source-capture selection");
|
|
209
|
+
};
|
|
210
|
+
const scriptsComplete = (completeness) => !completeness.truncated_sections.includes("scripts") &&
|
|
211
|
+
!completeness.unavailable_sections.includes("scripts") &&
|
|
212
|
+
completeness.dropped_events.scripts === 0;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createJavaScriptApplicationGraph, createJavaScriptApplicationNode, } from "./javascriptApplicationGraph.js";
|
|
2
|
-
import {
|
|
2
|
+
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
4
|
/** Merge source graphs, runtime nodes, and inferred mappings into one valid JAG. */
|
|
4
5
|
export const buildReconciledApplicationGraph = (input) => {
|
|
5
6
|
const merged = mergeNodes([
|
|
@@ -44,11 +45,11 @@ export const buildReconciledApplicationGraph = (input) => {
|
|
|
44
45
|
const boundGraphContent = (input, nodes, edges) => {
|
|
45
46
|
const allRoots = preferredRootIds(input);
|
|
46
47
|
const rootNodeIds = allRoots;
|
|
47
|
-
const sortedNodes = [...nodes].sort((left, right) =>
|
|
48
|
+
const sortedNodes = [...nodes].sort((left, right) => compareUnicodeCodePoints(left.node_id, right.node_id));
|
|
48
49
|
const retainedNodes = sortedNodes;
|
|
49
50
|
const retainedIds = new Set(retainedNodes.map(({ node_id: id }) => id));
|
|
50
51
|
const retainedEdges = [...edges]
|
|
51
|
-
.sort((left, right) =>
|
|
52
|
+
.sort((left, right) => compareUnicodeCodePoints(left.edge_id, right.edge_id))
|
|
52
53
|
.filter(({ source_node_id: source, target_node_id: target }) => retainedIds.has(source) && retainedIds.has(target));
|
|
53
54
|
return {
|
|
54
55
|
rootNodeIds,
|
|
@@ -143,7 +144,7 @@ const mergeNodes = (nodes) => {
|
|
|
143
144
|
...new Map(group
|
|
144
145
|
.flatMap(({ observations: values }) => values)
|
|
145
146
|
.map((observation) => [observation.observation_id, observation])).values(),
|
|
146
|
-
].sort((left, right) =>
|
|
147
|
+
].sort((left, right) => compareUnicodeCodePoints(left.observation_id, right.observation_id));
|
|
147
148
|
return createJavaScriptApplicationNode({
|
|
148
149
|
kind: first.kind,
|
|
149
150
|
identity: first.identity,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Prefix caller paths on a nested Zod validation boundary. */
|
|
3
|
+
export const parseAtPath = (parse, input, path) => {
|
|
4
|
+
try {
|
|
5
|
+
return parse(input);
|
|
6
|
+
}
|
|
7
|
+
catch (cause) {
|
|
8
|
+
if (cause instanceof z.ZodError)
|
|
9
|
+
throw new z.ZodError(cause.issues.map((issue) => ({
|
|
10
|
+
...issue,
|
|
11
|
+
path: [...path, ...issue.path],
|
|
12
|
+
})));
|
|
13
|
+
throw cause;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/** Represent one semantic caller constraint as a standard validation issue. */
|
|
17
|
+
export const invalidInput = (path, message) => new z.ZodError([{ code: "custom", path: [...path], message }]);
|
|
18
|
+
/** Verify an authenticated Evidence record against one runtime workflow. */
|
|
19
|
+
export const assertEvidenceIdentity = (evidence, expected, path) => {
|
|
20
|
+
if (evidence.operation !== expected.operation ||
|
|
21
|
+
evidence.predicate_type !== expected.predicate ||
|
|
22
|
+
evidence.provider.id !== expected.providerId ||
|
|
23
|
+
evidence.provider.name !== expected.providerName ||
|
|
24
|
+
evidence.provider.version !== expected.providerVersion ||
|
|
25
|
+
evidence.authority !== expected.authority ||
|
|
26
|
+
evidence.confidence !== expected.confidence)
|
|
27
|
+
throw invalidInput(path, `Evidence does not match the supported ${expected.operation} contract`);
|
|
28
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createJavaScriptApplicationEdge } from "./javascriptApplicationGraph.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
4
4
|
import { mappedRuntimePaths, } from "./javascriptRuntimeStaticCandidates.js";
|
|
5
5
|
/** Match runtime entities conservatively and emit only inferred observed_as edges. */
|
|
6
6
|
export const reconcileRuntimeEntities = (input) => {
|
|
7
7
|
const index = indexCandidates(input.candidates);
|
|
8
8
|
const evaluated = input.entities.map((entity) => reconcileEntity(entity, index, input.layers));
|
|
9
|
-
const retained = evaluated.sort((left, right) =>
|
|
9
|
+
const retained = evaluated.sort((left, right) => compareUnicodeCodePoints(left.item.reconciliation_id, right.item.reconciliation_id));
|
|
10
10
|
return {
|
|
11
11
|
items: retained.map(({ item }) => item),
|
|
12
12
|
edges: retained.flatMap(({ edge }) => (edge === null ? [] : [edge])),
|
|
@@ -105,7 +105,7 @@ const candidatesWithLocation = (entity, index, layers) => {
|
|
|
105
105
|
if (!located.has(key))
|
|
106
106
|
located.set(key, { candidate, mapping });
|
|
107
107
|
}
|
|
108
|
-
return [...located.values()].sort((left, right) =>
|
|
108
|
+
return [...located.values()].sort((left, right) => compareUnicodeCodePoints(candidateKey(left.candidate), candidateKey(right.candidate)));
|
|
109
109
|
};
|
|
110
110
|
const indexCandidates = (candidates) => {
|
|
111
111
|
const byCategoryDigest = new Map();
|
|
@@ -189,7 +189,7 @@ const createItem = (entity, input) => {
|
|
|
189
189
|
candidate_static_nodes: candidateReferences.items,
|
|
190
190
|
};
|
|
191
191
|
return {
|
|
192
|
-
reconciliation_id: `jrr_item_${
|
|
192
|
+
reconciliation_id: `jrr_item_${digestCanonicalValue(semantic, "Runtime reconciliation")}`,
|
|
193
193
|
...semantic,
|
|
194
194
|
};
|
|
195
195
|
};
|
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { webPageInspectionSchema, } from "../browserObservationSchemas.js";
|
|
4
|
-
import { classifyBrowserCompleteness, } from "../browserCompleteness.js";
|
|
5
|
-
import { electronPageInspectionSchema, } from "./electronObservation.js";
|
|
6
|
-
import { javascriptRuntimeObservationSchema, javascriptRuntimeKindSchema, } from "./javascriptRuntimeObservation.js";
|
|
7
|
-
import { canonicalDigest } from "../comparisonSemantics.js";
|
|
8
|
-
import { compareCodePoints } from "../canonicalOrdering.js";
|
|
1
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
2
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
9
3
|
import { parseEvidence } from "../evidence.js";
|
|
10
4
|
import { javascriptApplicationAnalysisResultSchema, } from "./javascriptApplicationAnalysis.js";
|
|
11
|
-
import {} from "./
|
|
12
|
-
import { parseActiveElectronCapture } from "./javascriptRuntimeReconciliationActive.js";
|
|
5
|
+
import { assertEvidenceIdentity, invalidInput, parseAtPath, } from "./javascriptRuntimeReconciliationInputValidation.js";
|
|
13
6
|
/** Parse and semantically bind every static analysis Evidence layer. */
|
|
14
|
-
export const parseStaticLayers = (layers) => layers
|
|
15
|
-
.map((layer) => parseStaticLayer(layer))
|
|
16
|
-
.sort((left, right) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.sort((left, right) => compareCodePoints(left.evidence.evidence_id, right.evidence.evidence_id));
|
|
21
|
-
const parseStaticLayer = (layer) => {
|
|
22
|
-
const evidence = parseEvidence(layer.analysis);
|
|
23
|
-
const result = javascriptApplicationAnalysisResultSchema.parse(evidence.normalized_result);
|
|
7
|
+
export const parseStaticLayers = (layers, path = ["static_layers"]) => layers
|
|
8
|
+
.map((layer, index) => parseStaticLayer(layer, [...path, index, "analysis"]))
|
|
9
|
+
.sort((left, right) => compareUnicodeCodePoints(left.layerId, right.layerId));
|
|
10
|
+
const parseStaticLayer = (layer, evidencePath) => {
|
|
11
|
+
const evidence = parseAtPath(parseEvidence, layer.analysis, evidencePath);
|
|
12
|
+
const result = parseAtPath((value) => javascriptApplicationAnalysisResultSchema.parse(value), evidence.normalized_result, [...evidencePath, "normalized_result"]);
|
|
24
13
|
assertEvidenceIdentity(evidence, {
|
|
25
14
|
operation: "analyze_javascript_application",
|
|
26
15
|
predicate: "rea.javascript-application-analysis",
|
|
@@ -29,14 +18,14 @@ const parseStaticLayer = (layer) => {
|
|
|
29
18
|
providerVersion: "1",
|
|
30
19
|
authority: "shipped-artifact",
|
|
31
20
|
confidence: "derived",
|
|
32
|
-
});
|
|
21
|
+
}, evidencePath);
|
|
33
22
|
if (evidence.subject === null ||
|
|
34
23
|
evidence.subject.digest.sha256 !== result.root_artifact_sha256 ||
|
|
35
24
|
evidence.subject.format !== result.format ||
|
|
36
25
|
evidence.subject.local_path !== result.input_path)
|
|
37
|
-
throw
|
|
26
|
+
throw invalidInput([...evidencePath, "subject"], "JavaScript application Evidence subject disagrees with its result");
|
|
38
27
|
return {
|
|
39
|
-
layerId: `jrl_${
|
|
28
|
+
layerId: `jrl_${digestCanonicalValue({
|
|
40
29
|
role: layer.role,
|
|
41
30
|
evidence_id: evidence.evidence_id,
|
|
42
31
|
runtime_mappings: layer.runtime_mappings,
|
|
@@ -48,203 +37,3 @@ const parseStaticLayer = (layer) => {
|
|
|
48
37
|
runtimeMappings: layer.runtime_mappings,
|
|
49
38
|
};
|
|
50
39
|
};
|
|
51
|
-
const parseRuntimeCapture = (input) => {
|
|
52
|
-
const evidence = parseEvidence(input);
|
|
53
|
-
if (evidence.operation === "inspect_web_page") {
|
|
54
|
-
assertEvidenceIdentity(evidence, {
|
|
55
|
-
operation: "inspect_web_page",
|
|
56
|
-
predicate: "rea.web-page-inspection",
|
|
57
|
-
providerId: "rea-cdp-browser",
|
|
58
|
-
providerName: "REA Chrome DevTools Protocol observation provider",
|
|
59
|
-
providerVersion: "2",
|
|
60
|
-
authority: "external-service",
|
|
61
|
-
confidence: "observed",
|
|
62
|
-
});
|
|
63
|
-
const inspection = webPageInspectionSchema.parse(evidence.normalized_result);
|
|
64
|
-
assertRuntimeParameters(evidence, {
|
|
65
|
-
kind: "browser",
|
|
66
|
-
targetId: inspection.target.target_id,
|
|
67
|
-
targetOrigin: inspection.target.origin,
|
|
68
|
-
sourceIncluded: inspection.scripts.items.some(({ source }) => source.included),
|
|
69
|
-
});
|
|
70
|
-
return {
|
|
71
|
-
kind: "browser",
|
|
72
|
-
evidence,
|
|
73
|
-
inspection,
|
|
74
|
-
captureSha256: canonicalDigest(inspection, "Runtime reconciliation"),
|
|
75
|
-
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
if (evidence.operation === "inspect_electron_page") {
|
|
79
|
-
assertEvidenceIdentity(evidence, {
|
|
80
|
-
operation: "inspect_electron_page",
|
|
81
|
-
predicate: "rea.electron-page-inspection",
|
|
82
|
-
providerId: "rea-cdp-electron",
|
|
83
|
-
providerName: "REA Electron file-page CDP observation provider",
|
|
84
|
-
providerVersion: "1",
|
|
85
|
-
authority: "external-service",
|
|
86
|
-
confidence: "observed",
|
|
87
|
-
});
|
|
88
|
-
const inspection = electronPageInspectionSchema.parse(evidence.normalized_result);
|
|
89
|
-
assertRuntimeParameters(evidence, {
|
|
90
|
-
kind: "electron",
|
|
91
|
-
targetId: inspection.target.target_id,
|
|
92
|
-
sourceIncluded: inspection.scripts.items.some(({ source }) => source.included),
|
|
93
|
-
});
|
|
94
|
-
return {
|
|
95
|
-
kind: "electron",
|
|
96
|
-
evidence,
|
|
97
|
-
inspection,
|
|
98
|
-
captureSha256: canonicalDigest(inspection, "Runtime reconciliation"),
|
|
99
|
-
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
if (evidence.operation === "observe_javascript_runtime") {
|
|
103
|
-
assertEvidenceIdentity(evidence, {
|
|
104
|
-
operation: "observe_javascript_runtime",
|
|
105
|
-
predicate: "rea.javascript-runtime-observation",
|
|
106
|
-
providerId: "rea-v8-inspector",
|
|
107
|
-
providerName: "REA passive Node/Electron V8 Inspector provider",
|
|
108
|
-
providerVersion: "1",
|
|
109
|
-
authority: "external-service",
|
|
110
|
-
confidence: "observed",
|
|
111
|
-
});
|
|
112
|
-
const result = javascriptRuntimeObservationSchema.parse(evidence.normalized_result);
|
|
113
|
-
assertV8RuntimeParameters(evidence, result);
|
|
114
|
-
const inspection = normalizeV8Inspection(result);
|
|
115
|
-
return {
|
|
116
|
-
kind: "v8-inspector",
|
|
117
|
-
evidence,
|
|
118
|
-
inspection,
|
|
119
|
-
captureSha256: canonicalDigest(result, "Runtime reconciliation"),
|
|
120
|
-
scriptsCompleteWithinScope: false,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
if (evidence.operation === "capture_electron_scenario") {
|
|
124
|
-
return parseActiveElectronCapture(evidence);
|
|
125
|
-
}
|
|
126
|
-
throw new TypeError("Runtime reconciliation requires inspect_web_page, inspect_electron_page, observe_javascript_runtime, or capture_electron_scenario Evidence");
|
|
127
|
-
};
|
|
128
|
-
const assertV8RuntimeParameters = (evidence, result) => {
|
|
129
|
-
const parameters = z
|
|
130
|
-
.object({
|
|
131
|
-
inspector_endpoint: browserEndpointSchema,
|
|
132
|
-
target_id: z.string().trim().min(1),
|
|
133
|
-
runtime_kind: javascriptRuntimeKindSchema.optional(),
|
|
134
|
-
})
|
|
135
|
-
.passthrough()
|
|
136
|
-
.parse(evidence.parameters);
|
|
137
|
-
if (parameters.target_id !== result.target.target_id ||
|
|
138
|
-
(parameters.runtime_kind !== undefined &&
|
|
139
|
-
parameters.runtime_kind !== result.target.runtime_kind))
|
|
140
|
-
throw new TypeError("Runtime Evidence target or declared role disagrees with its result");
|
|
141
|
-
for (const location of [
|
|
142
|
-
result.target.location,
|
|
143
|
-
...result.scripts.items.map(({ location }) => location),
|
|
144
|
-
])
|
|
145
|
-
if (location.kind === "builtin" && !location.specifier.startsWith("node:"))
|
|
146
|
-
throw new TypeError("Runtime Evidence contains an invalid builtin location");
|
|
147
|
-
};
|
|
148
|
-
const normalizeV8Inspection = (result) => ({
|
|
149
|
-
target: {
|
|
150
|
-
target_id: result.target.target_id,
|
|
151
|
-
type: result.target.protocol_type,
|
|
152
|
-
title: result.target.runtime_kind,
|
|
153
|
-
attached: result.target.attached,
|
|
154
|
-
...(result.target.location.kind === "unresolved"
|
|
155
|
-
? { unresolved_location: result.target.location }
|
|
156
|
-
: runtimeLocation(result.target.location)),
|
|
157
|
-
},
|
|
158
|
-
frames: [],
|
|
159
|
-
scripts: {
|
|
160
|
-
items: result.scripts.items.map((script) => ({
|
|
161
|
-
script_key: script.script_key,
|
|
162
|
-
frame_id: script.execution_context_key,
|
|
163
|
-
...runtimeLocation(script.location),
|
|
164
|
-
cdp_hash: script.cdp_hash,
|
|
165
|
-
length: script.length,
|
|
166
|
-
is_module: script.is_module,
|
|
167
|
-
language: null,
|
|
168
|
-
source: {
|
|
169
|
-
included: false,
|
|
170
|
-
reason: "V8 Inspector source capture is outside passive authority.",
|
|
171
|
-
},
|
|
172
|
-
})),
|
|
173
|
-
},
|
|
174
|
-
workers: [],
|
|
175
|
-
completeness: classifyBrowserCompleteness({
|
|
176
|
-
policyFilteredSections: new Set(excludedV8Scripts(result) > 0 ? ["scripts"] : []),
|
|
177
|
-
attachLimitedSections: new Set([
|
|
178
|
-
"frames",
|
|
179
|
-
"scripts",
|
|
180
|
-
"script_sources",
|
|
181
|
-
"workers",
|
|
182
|
-
]),
|
|
183
|
-
truncatedSections: new Set(result.capture.truncated ? ["scripts"] : []),
|
|
184
|
-
unavailableSections: new Set(["frames", "script_sources", "workers"]),
|
|
185
|
-
excluded: excludedV8Scripts(result) === 0
|
|
186
|
-
? []
|
|
187
|
-
: [
|
|
188
|
-
{
|
|
189
|
-
section: "scripts",
|
|
190
|
-
reason: "out_of_target_scope",
|
|
191
|
-
count: excludedV8Scripts(result),
|
|
192
|
-
},
|
|
193
|
-
],
|
|
194
|
-
droppedEvents: {
|
|
195
|
-
scripts: result.capture.events_dropped,
|
|
196
|
-
network_requests: 0,
|
|
197
|
-
console_events: 0,
|
|
198
|
-
websocket_connections: 0,
|
|
199
|
-
websocket_frames: 0,
|
|
200
|
-
webmcp_tools: 0,
|
|
201
|
-
timeline_events: 0,
|
|
202
|
-
},
|
|
203
|
-
}),
|
|
204
|
-
});
|
|
205
|
-
const runtimeLocation = (location) => {
|
|
206
|
-
if (location.kind === "file")
|
|
207
|
-
return { file_path: location.file_path };
|
|
208
|
-
if (location.kind === "url")
|
|
209
|
-
return { url: location.sanitized_url };
|
|
210
|
-
return { url: location.specifier };
|
|
211
|
-
};
|
|
212
|
-
const excludedV8Scripts = (result) => Object.values(result.scripts.excluded).reduce((total, count) => total + count, 0);
|
|
213
|
-
const assertRuntimeParameters = (evidence, expected) => {
|
|
214
|
-
const common = {
|
|
215
|
-
target_id: z.string().trim().min(1),
|
|
216
|
-
cdp_endpoint: browserEndpointSchema,
|
|
217
|
-
include_script_sources: z.boolean(),
|
|
218
|
-
};
|
|
219
|
-
if (expected.kind === "browser") {
|
|
220
|
-
const parameters = z
|
|
221
|
-
.object({ ...common, allowed_origins: browserAllowedOriginsSchema })
|
|
222
|
-
.passthrough()
|
|
223
|
-
.parse(evidence.parameters);
|
|
224
|
-
if (parameters.target_id !== expected.targetId)
|
|
225
|
-
throw new TypeError("Runtime Evidence target disagrees with its captured result");
|
|
226
|
-
if (!parameters.allowed_origins.includes(expected.targetOrigin))
|
|
227
|
-
throw new TypeError("Browser Evidence target is outside its recorded origin scope");
|
|
228
|
-
if (expected.sourceIncluded && !parameters.include_script_sources)
|
|
229
|
-
throw new TypeError("Runtime Evidence contains source without source-capture selection");
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
const parameters = z.object(common).passthrough().parse(evidence.parameters);
|
|
233
|
-
if (parameters.target_id !== expected.targetId)
|
|
234
|
-
throw new TypeError("Runtime Evidence target disagrees with its captured result");
|
|
235
|
-
if (expected.sourceIncluded && !parameters.include_script_sources)
|
|
236
|
-
throw new TypeError("Runtime Evidence contains source without source-capture selection");
|
|
237
|
-
};
|
|
238
|
-
const scriptsComplete = (completeness) => !completeness.truncated_sections.includes("scripts") &&
|
|
239
|
-
!completeness.unavailable_sections.includes("scripts") &&
|
|
240
|
-
completeness.dropped_events.scripts === 0;
|
|
241
|
-
const assertEvidenceIdentity = (evidence, expected) => {
|
|
242
|
-
if (evidence.operation !== expected.operation ||
|
|
243
|
-
evidence.predicate_type !== expected.predicate ||
|
|
244
|
-
evidence.provider.id !== expected.providerId ||
|
|
245
|
-
evidence.provider.name !== expected.providerName ||
|
|
246
|
-
evidence.provider.version !== expected.providerVersion ||
|
|
247
|
-
evidence.authority !== expected.authority ||
|
|
248
|
-
evidence.confidence !== expected.confidence)
|
|
249
|
-
throw new TypeError(`Evidence does not match the supported ${expected.operation} contract`);
|
|
250
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {} from "./javascriptApplicationGraph.js";
|
|
2
|
-
import {
|
|
2
|
+
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
3
3
|
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
4
4
|
import { javascriptRuntimeReconciliationResultSchema, } from "./javascriptRuntimeReconciliationSchemas.js";
|
|
5
5
|
/** Build and verify the deterministic caller-visible reconciliation result. */
|
|
@@ -21,7 +21,7 @@ export const createJavaScriptRuntimeReconciliationResult = (input) => {
|
|
|
21
21
|
limitations: reconciliationLimitations(completion),
|
|
22
22
|
};
|
|
23
23
|
return javascriptRuntimeReconciliationResultSchema.parse({
|
|
24
|
-
reconciliation_id: `jrr_${
|
|
24
|
+
reconciliation_id: `jrr_${digestCanonicalValue(semantic, "Runtime reconciliation")}`,
|
|
25
25
|
...semantic,
|
|
26
26
|
});
|
|
27
27
|
};
|
|
@@ -86,9 +86,14 @@ const frameEntities = (capture) => capture.inspection.frames.map((frame) => {
|
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
const scriptEntities = (capture) => capture.inspection.scripts.items.map((script) => {
|
|
89
|
-
const location = "
|
|
90
|
-
? {
|
|
91
|
-
|
|
89
|
+
const location = "unresolved_location" in script
|
|
90
|
+
? {
|
|
91
|
+
kind: "unresolved",
|
|
92
|
+
value: script.unresolved_location.reported_url,
|
|
93
|
+
}
|
|
94
|
+
: "url" in script
|
|
95
|
+
? { kind: "url", value: script.url }
|
|
96
|
+
: { kind: "file", value: script.file_path };
|
|
92
97
|
return runtimeEntity(capture, {
|
|
93
98
|
kind: "script",
|
|
94
99
|
nodeKind: "runtime-script-instance",
|
|
@@ -103,7 +108,13 @@ const scriptEntities = (capture) => capture.inspection.scripts.items.map((script
|
|
|
103
108
|
: null,
|
|
104
109
|
label: location.value,
|
|
105
110
|
properties: {
|
|
106
|
-
|
|
111
|
+
...("unresolved_location" in script
|
|
112
|
+
? {
|
|
113
|
+
location_kind: "unresolved",
|
|
114
|
+
reported_url: script.unresolved_location.reported_url,
|
|
115
|
+
location_reason: script.unresolved_location.reason,
|
|
116
|
+
}
|
|
117
|
+
: { location: location.value }),
|
|
107
118
|
cdp_hash: script.cdp_hash,
|
|
108
119
|
length: script.length,
|
|
109
120
|
is_module: script.is_module,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
3
|
import { evidenceSchema } from "../evidence.js";
|
|
4
4
|
import { javascriptRuntimeUnresolvedLocationSchema } from "./javascriptRuntimeObservation.js";
|
|
5
5
|
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
|
|
@@ -64,7 +64,7 @@ const staticLayerSchema = z.strictObject({
|
|
|
64
64
|
function normalizeRuntimeMappings(mappings) {
|
|
65
65
|
return [
|
|
66
66
|
...new Map(mappings.map((mapping) => [runtimeMappingKey(mapping), mapping])).values(),
|
|
67
|
-
].sort((left, right) =>
|
|
67
|
+
].sort((left, right) => compareUnicodeCodePoints(runtimeMappingKey(left), runtimeMappingKey(right)));
|
|
68
68
|
}
|
|
69
69
|
function runtimeMappingKey(mapping) {
|
|
70
70
|
return mapping.kind === "file-root"
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { posix, relative, win32 } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
3
4
|
/** Index statically reconstructed entities that can receive runtime matches. */
|
|
4
5
|
export const collectStaticRuntimeCandidates = (layers) => layers
|
|
5
6
|
.flatMap((layer) => candidatesForLayer(layer))
|
|
6
|
-
.sort((left, right) =>
|
|
7
|
-
|
|
7
|
+
.sort((left, right) => compareUnicodeCodePoints(left.layer.layerId, right.layer.layerId) ||
|
|
8
|
+
compareUnicodeCodePoints(left.node.node_id, right.node.node_id));
|
|
8
9
|
/** Translate one already-authorized runtime location into artifact paths. */
|
|
9
10
|
export const mappedRuntimePaths = (layer, entity) => {
|
|
10
11
|
const paths = [];
|
|
@@ -186,7 +187,7 @@ const activeArtifactPrefixes = (layer, entities) => {
|
|
|
186
187
|
? pathBelowUrlPrefix(mapping.prefix, location.value) !== null
|
|
187
188
|
: false))
|
|
188
189
|
prefixes.add(mapping.artifact_prefix);
|
|
189
|
-
return [...prefixes].sort(
|
|
190
|
+
return [...prefixes].sort(compareUnicodeCodePoints);
|
|
190
191
|
};
|
|
191
192
|
const pathWithinPrefix = (path, prefix) => prefix === "" || path === prefix || path.startsWith(`${prefix}/`);
|
|
192
193
|
const safeArtifactPath = (prefix, suffix) => normalizeArtifactPath(prefix === "" ? suffix : posix.join(prefix, suffix));
|
|
@@ -204,5 +205,5 @@ const normalizeArtifactPath = (value) => {
|
|
|
204
205
|
};
|
|
205
206
|
const uniqueMappedPaths = (values) => [
|
|
206
207
|
...new Map(values.map((value) => [`${value.basis}:${value.path}`, value])).values(),
|
|
207
|
-
].sort((left, right) =>
|
|
208
|
-
|
|
208
|
+
].sort((left, right) => compareUnicodeCodePoints(left.path, right.path) ||
|
|
209
|
+
compareUnicodeCodePoints(left.basis, right.basis));
|