rea-agents 6.0.0 → 6.1.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.
Files changed (343) hide show
  1. package/README.md +23 -17
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +196 -33
  10. package/dist/android/JadxMcpTransport.js +4 -0
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +19 -2
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/CallPathTracing.js +19 -3
  18. package/dist/application/CapabilityInventory.js +6 -3
  19. package/dist/application/ClientConfigurationDocument.js +871 -6
  20. package/dist/application/ClientRegistrationIdentity.js +26 -5
  21. package/dist/application/ClientRegistrationStatus.js +29 -14
  22. package/dist/application/DirectAnalysis.js +27 -37
  23. package/dist/application/Doctor.js +4 -2
  24. package/dist/application/DoctorScope.js +25 -13
  25. package/dist/application/EnhancedLiteralTracing.js +22 -25
  26. package/dist/application/EnhancedTools.js +13 -11
  27. package/dist/application/EvidenceBundleFiles.js +23 -11
  28. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  29. package/dist/application/InventoryProjectionEvidence.js +4 -3
  30. package/dist/application/InvestigationProviders.js +3 -2
  31. package/dist/application/JsonFiles.js +50 -28
  32. package/dist/application/ProcedureAddressResolution.js +11 -0
  33. package/dist/application/ReconstructionCoverageService.js +7 -4
  34. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  35. package/dist/application/Setup.js +13 -1
  36. package/dist/application/SetupClientConfiguration.js +10 -15
  37. package/dist/application/SetupHost.js +5 -2
  38. package/dist/application/SetupPlan.js +5 -3
  39. package/dist/application/SupportedClients.js +34 -1
  40. package/dist/application/Uninstall.js +4 -3
  41. package/dist/application/Update.js +18 -3
  42. package/dist/application/UpdateRuntime.js +46 -25
  43. package/dist/application/WebModuleTraceService.js +4 -2
  44. package/dist/application/WebNetworkCaptureService.js +4 -2
  45. package/dist/application/WebRuntimeService.js +5 -3
  46. package/dist/application/WebScriptExportService.js +2 -2
  47. package/dist/application/WebSourceLocationService.js +4 -2
  48. package/dist/application/WorkflowEvidence.js +82 -0
  49. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  50. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  51. package/dist/application/binary/AnalysisSnapshotCache.js +3 -6
  52. package/dist/application/binary/BinarySession.js +95 -68
  53. package/dist/application/binary/BinarySessionOpen.js +3 -3
  54. package/dist/application/binary/BinarySessionRecords.js +25 -3
  55. package/dist/application/binary/BinarySessionStatus.js +17 -1
  56. package/dist/application/binary/CompositeProvider.js +13 -0
  57. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  58. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  59. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  60. package/dist/application/evm/EvmInterfaceService.js +4 -2
  61. package/dist/application/investigation/EvidenceLedger.js +21 -7
  62. package/dist/application/investigation/InvestigationRecords.js +8 -0
  63. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  64. package/dist/application/javascript/JavaScriptApplicationEvidence.js +24 -3
  65. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  66. package/dist/application/javascript/JavaScriptApplicationService.js +22 -15
  67. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  68. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -4
  69. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  70. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +6 -3
  71. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +11 -3
  72. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  73. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  74. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  75. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  76. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  77. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +23 -1
  78. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  79. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  80. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  81. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  82. package/dist/application/process/ProcessCli.js +14 -6
  83. package/dist/application/process/ProcessEvidence.js +4 -3
  84. package/dist/application/workflowInputError.js +18 -0
  85. package/dist/artifacts/ArtifactProvider.js +12 -2
  86. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  87. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  88. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  89. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  90. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  91. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  92. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  93. package/dist/artifacts/apple/NibArchive.js +81 -14
  94. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  95. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  96. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +13 -8
  97. package/dist/artifacts/inventory/scanCanonical.js +11 -14
  98. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  99. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  100. package/dist/browser/CdpCaptureEventHandlers.js +76 -11
  101. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  102. package/dist/browser/CdpCaptureEvents.js +25 -0
  103. package/dist/browser/CdpConnection.js +30 -11
  104. package/dist/browser/CdpOptionalCommand.js +2 -3
  105. package/dist/browser/CdpPageCapture.js +23 -1
  106. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  107. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  108. package/dist/browser/PlaywrightElectronActiveProvider.js +123 -124
  109. package/dist/browser/WebSourceMapFetcher.js +426 -72
  110. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  111. package/dist/browser/history/CaptureFailures.js +37 -1
  112. package/dist/browser/history/CaptureRelease.js +5 -0
  113. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  114. package/dist/browser/history/HarJson.js +3 -2
  115. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  116. package/dist/cli/analysisSelector.js +23 -0
  117. package/dist/cli/applicationCommands.js +2 -3
  118. package/dist/cli/coreBinaryCommands.js +70 -12
  119. package/dist/cli/electronCommands.js +7 -6
  120. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  121. package/dist/cli/jsonOutput.js +4 -99
  122. package/dist/cli/nativeCallCommands.js +2 -3
  123. package/dist/cli/webRuntimeCommands.js +8 -8
  124. package/dist/cli.js +2 -1
  125. package/dist/cliCommandNames.js +0 -1
  126. package/dist/cliJsonInput.js +9 -4
  127. package/dist/config/environment.js +4 -0
  128. package/dist/config/ghidraStartupTimeout.js +17 -0
  129. package/dist/config/mcpResponseBudget.js +22 -0
  130. package/dist/config/parseConfig.js +2 -1
  131. package/dist/contracts/enhancedInputs.js +5 -3
  132. package/dist/contracts/enhancedToolContracts.js +3 -3
  133. package/dist/contracts/hopperMemoryContracts.js +2 -5
  134. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  135. package/dist/contracts/managed/managedToolContracts.js +2 -4
  136. package/dist/contracts/native/nativeToolContracts.js +4 -2
  137. package/dist/contracts/officialToolContracts.js +14 -15
  138. package/dist/contracts/promptContracts.js +3 -3
  139. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  140. package/dist/contracts/sessionStatusContract.js +2 -4
  141. package/dist/contracts/sessionToolContracts.js +4 -6
  142. package/dist/contracts/sessionToolSchemas.js +2 -5
  143. package/dist/contracts/toolContractExamples.js +0 -1
  144. package/dist/contracts/toolContractHelpers.js +4 -1
  145. package/dist/contracts/toolEffects.js +0 -1
  146. package/dist/contracts/toolOutputSchemaGroups.js +28 -27
  147. package/dist/contracts/toolOutputSchemaPrimitives.js +18 -0
  148. package/dist/contracts/toolSchemaMetadata.js +69 -10
  149. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  150. package/dist/domain/analysisErrorBase.js +8 -3
  151. package/dist/domain/analysisErrorCore.js +3 -1
  152. package/dist/domain/analysisErrorPresentation.js +72 -17
  153. package/dist/domain/analysisErrorProjection.js +106 -27
  154. package/dist/domain/android/androidAnalysis.js +2 -4
  155. package/dist/domain/android/androidApplication.js +17 -9
  156. package/dist/domain/apple/appleApplication.js +41 -14
  157. package/dist/domain/apple/dyldEnvironment.js +73 -0
  158. package/dist/domain/apple/dylibResolution.js +120 -9
  159. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  160. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  161. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  162. package/dist/domain/apple/keyedArchive.js +9 -1
  163. package/dist/domain/apple/machoContainer.js +54 -0
  164. package/dist/domain/apple/plistNumbers.js +76 -0
  165. package/dist/domain/artifactIdentity.js +29 -0
  166. package/dist/domain/artifactInventoryEvidence.js +19 -24
  167. package/dist/domain/bridgeCandidateProjection.js +71 -0
  168. package/dist/domain/browserCompleteness.js +1 -0
  169. package/dist/domain/browserObservationError.js +24 -5
  170. package/dist/domain/browserScenarioValues.js +2 -6
  171. package/dist/domain/bundleComparison.js +3 -2
  172. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  173. package/dist/domain/canonicalOrdering.js +9 -5
  174. package/dist/domain/changedBehavior.js +6 -6
  175. package/dist/domain/comparisonSourceEvidence.js +40 -0
  176. package/dist/domain/configurationErrors.js +1 -1
  177. package/dist/domain/evidence.js +64 -9
  178. package/dist/domain/evidenceBundle.js +42 -1
  179. package/dist/domain/evidenceErrors.js +12 -1
  180. package/dist/domain/explicitSensitiveFailure.js +17 -1
  181. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  182. package/dist/domain/hopperErrors.js +23 -2
  183. package/dist/domain/hopperValues.js +51 -8
  184. package/dist/domain/immutableJson.js +114 -0
  185. package/dist/domain/inputIssueProjection.js +3 -0
  186. package/dist/domain/javascript/electronActiveObservation.js +30 -4
  187. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  188. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  189. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  190. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  191. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  192. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  193. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  194. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  195. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  196. package/dist/domain/javascript/javascriptSemanticGraph.js +13 -0
  197. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  198. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  199. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  200. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  201. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  202. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  203. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  204. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  205. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  206. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  207. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  208. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  209. package/dist/domain/jsonSerialization.js +109 -0
  210. package/dist/domain/jsonValue.js +90 -6
  211. package/dist/domain/localPath.js +6 -0
  212. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  213. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  214. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  215. package/dist/domain/managed/managedNativeVerification.js +3 -9
  216. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  217. package/dist/domain/native/nativeCallObservation.js +33 -11
  218. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  219. package/dist/domain/process/processCapture.js +8 -4
  220. package/dist/domain/process/processComparison.js +38 -4
  221. package/dist/domain/process/processScenario.js +11 -10
  222. package/dist/domain/propertyListKeys.js +1 -1
  223. package/dist/domain/propertyListXmlText.js +19 -0
  224. package/dist/domain/providerAdapterError.js +1 -1
  225. package/dist/domain/providerOperationHealth.js +54 -0
  226. package/dist/domain/reconstructionVerification.js +6 -43
  227. package/dist/domain/reconstructionVerificationSchemas.js +2 -2
  228. package/dist/domain/staticRuntimeCorrelation.js +6 -43
  229. package/dist/domain/webBundleAnalysis.js +20 -8
  230. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  231. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  232. package/dist/domain/webRuntime.js +19 -5
  233. package/dist/domain/webSourceLocation.js +1 -0
  234. package/dist/firmware/FirmwareFiles.js +1 -1
  235. package/dist/generatedPackageMetadata.js +1 -1
  236. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  237. package/dist/ghidra/GhidraClient.js +47 -14
  238. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  239. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  240. package/dist/ghidra/GhidraInstallation.js +18 -21
  241. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  242. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  243. package/dist/ghidra/GhidraLauncher.js +33 -16
  244. package/dist/ghidra/GhidraProviderCapabilities.js +14 -2
  245. package/dist/ghidra/GhidraProviderClient.js +23 -12
  246. package/dist/ghidra/GhidraSessionError.js +11 -7
  247. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  248. package/dist/ghidra/GhidraTransport.js +20 -0
  249. package/dist/hopper/BridgeLauncher.js +31 -11
  250. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  251. package/dist/hopper/HopperCleanup.js +15 -3
  252. package/dist/hopper/HopperClient.js +222 -14
  253. package/dist/hopper/HopperFileOffset.js +237 -0
  254. package/dist/hopper/HopperMachOImage.js +196 -0
  255. package/dist/hopper/HopperOperationStage.js +6 -0
  256. package/dist/hopper/HopperProvider.js +63 -9
  257. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  258. package/dist/hopper/HopperRegexSearch.js +137 -0
  259. package/dist/hopper/HopperRegexWorker.js +27 -0
  260. package/dist/hopper/HopperRequestQueue.js +68 -19
  261. package/dist/hopper/HopperTargetLease.js +3 -2
  262. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  263. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  264. package/dist/inspector/V8InspectorProvider.js +47 -11
  265. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  266. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  267. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  268. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  269. package/dist/mcpDoctor.js +62 -2
  270. package/dist/native/AppleDispatchCoverage.js +47 -6
  271. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  272. package/dist/native/AppleDispatchMetadata.js +6 -3
  273. package/dist/native/AppleMachoFixups.js +48 -24
  274. package/dist/native/AppleMachoSelection.js +32 -16
  275. package/dist/native/AppleObjcCategories.js +6 -2
  276. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  277. package/dist/native/AppleObjcProperties.js +2 -1
  278. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  279. package/dist/native/AppleSwiftVtables.js +21 -15
  280. package/dist/native/CommandRunner.js +81 -84
  281. package/dist/native/LldbCallTracer.js +365 -102
  282. package/dist/native/LldbRetainedObservations.js +178 -0
  283. package/dist/native/NativeCallObservation.js +62 -3
  284. package/dist/native/NativeMacOSProvider.js +98 -17
  285. package/dist/native/SignatureTargetBinding.js +155 -0
  286. package/dist/native/parsers/lipo.js +71 -1
  287. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  288. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  289. package/dist/process/DarwinProcessRunTokenReader.js +8 -9
  290. package/dist/process/ExecFileOutput.js +20 -0
  291. package/dist/process/OwnedCommand.js +7 -2
  292. package/dist/process/ProcessOwnership.js +203 -53
  293. package/dist/process/ProcessOwnershipObservation.js +49 -4
  294. package/dist/process/ProviderProcess.js +38 -7
  295. package/dist/process/capture/ProcessCaptureError.js +2 -2
  296. package/dist/process/capture/ProcessCaptureLifecycle.js +100 -34
  297. package/dist/server/EvidenceMcpServer.js +146 -0
  298. package/dist/server/createServer.js +15 -8
  299. package/dist/server/registerAndroidTools.js +2 -4
  300. package/dist/server/registerApplicationTools/helpers.js +2 -4
  301. package/dist/server/registerArtifactComparisonTool.js +11 -7
  302. package/dist/server/registerBinaryDiagnosticsTools.js +2 -4
  303. package/dist/server/registerBrowserScenarioTool.js +2 -4
  304. package/dist/server/registerBrowserTools.js +2 -4
  305. package/dist/server/registerBundleComparisonTool.js +2 -3
  306. package/dist/server/registerCloseLifecycleTool.js +8 -18
  307. package/dist/server/registerElectronTools.js +2 -4
  308. package/dist/server/registerEnhancedTools.js +18 -59
  309. package/dist/server/registerEvidenceTools.js +2 -4
  310. package/dist/server/registerEvmTools.js +2 -4
  311. package/dist/server/registerFirmwareTools.js +2 -4
  312. package/dist/server/registerFunctionComparisonTool.js +10 -6
  313. package/dist/server/registerInvestigationTools.js +7 -7
  314. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  315. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  316. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  317. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  318. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  319. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  320. package/dist/server/registerOfficialTools.js +2 -4
  321. package/dist/server/registerProcessComparisonTool.js +71 -45
  322. package/dist/server/registerRecordedCrashTools.js +2 -4
  323. package/dist/server/registerSessionRecordTools.js +5 -6
  324. package/dist/server/registerSessionStatusTool.js +17 -3
  325. package/dist/server/registerSessionTools.js +11 -3
  326. package/dist/server/registerWebModuleTool.js +2 -4
  327. package/dist/server/registerWebNetworkCaptureTool.js +2 -4
  328. package/dist/server/registerWebRuntimeTools.js +3 -7
  329. package/dist/server/registerWebScriptTool.js +2 -4
  330. package/dist/server/registerWebSourceLocationTool.js +2 -4
  331. package/dist/server/runDerivedOperation.js +15 -3
  332. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  333. package/dist/server/toolRegistrationOptions.js +2 -2
  334. package/dist/server/toolResult.js +62 -10
  335. package/dist/server/toolResultEncoding.js +33 -0
  336. package/install.sh +1 -1
  337. package/native/windows/build/manifest.json +1 -1
  338. package/package.json +8 -3
  339. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  340. package/scripts/electron-active-hook.cjs +241 -37
  341. package/skills/reverse-engineer-anything/SKILL.md +11 -3
  342. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  343. package/dist/ghidra/GhidraDefaults.js +0 -2
@@ -1,12 +1,10 @@
1
1
  import { EnhancedTools, } from "../application/EnhancedTools.js";
2
- import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
2
+ import { createWorkflowEvidence, workflowSnapshotRecord, recordWorkflowUnknowns, } from "../application/WorkflowEvidence.js";
3
3
  import { toolContract } from "../contracts/toolContracts.js";
4
- import { UnknownRegistryError } from "../domain/unknownRegistryError.js";
5
- import { createEvidence } from "../domain/evidence.js";
6
4
  import { mcpProgressReporter } from "./mcpProgress.js";
7
5
  import { logToolExecution } from "./toolLogging.js";
8
6
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
- import { toCallToolResult } from "./toolResult.js";
7
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
10
8
  import { executeFunctionAnalysisEvidence } from "../application/FunctionAnalysisEvidence.js";
11
9
  /** Register composed workflows against the same port as direct bridge tools. */
12
10
  // oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
@@ -114,24 +112,25 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
114
112
  terminal: true,
115
113
  });
116
114
  if (result.ok) {
117
- const upstreamProfile = registration.analysisProfile?.();
118
- const evidence = createEvidence(registration.activeTarget?.(), REA_WORKFLOW_PROVIDER, {
115
+ const evidence = createWorkflowEvidence({
116
+ target: registration.activeTarget?.(),
119
117
  operation: name,
120
118
  parameters,
121
119
  result: result.value,
122
- ...(upstreamProfile === undefined
123
- ? {}
124
- : {
125
- analysisProfile: workflowAnalysisProfile(upstreamProfile),
126
- }),
127
- confidence: "derived",
128
- limitations: [
129
- "Derived by an REA workflow from one or more provider observations.",
130
- ],
120
+ upstreamProfile: registration.analysisProfile?.(),
131
121
  });
132
122
  const recorded = registration.recordEvidence?.(evidence);
133
123
  if (recorded !== undefined && !recorded.ok)
134
124
  return toCallToolResult(recorded, contract);
125
+ if (name !== "trace_native_ui_action" &&
126
+ registration.allowsSnapshotReplay?.(name) === true) {
127
+ const workflowRecord = workflowSnapshotRecord(evidence, name);
128
+ if (workflowRecord !== undefined) {
129
+ const snapshot = registration.recordWorkflowSnapshot?.(workflowRecord);
130
+ if (snapshot !== undefined && !snapshot.ok)
131
+ return toCallToolResult(snapshot, contract);
132
+ }
133
+ }
135
134
  const unknowns = recordWorkflowUnknowns({
136
135
  name,
137
136
  result: result.value,
@@ -140,7 +139,7 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
140
139
  });
141
140
  if (!unknowns.ok)
142
141
  return toCallToolResult(unknowns, contract);
143
- return toCallToolResult({ ok: true, value: evidence }, contract);
142
+ return toEvidenceToolResult(evidence, contract, recorded);
144
143
  }
145
144
  return toCallToolResult(result, contract);
146
145
  };
@@ -158,48 +157,8 @@ const executeFunctionTool = async (analysis, registration, contract, request) =>
158
157
  message: result.ok ? "completed" : "failed",
159
158
  terminal: true,
160
159
  });
161
- if (result.ok) {
162
- const recorded = registration.recordEvidence?.(result.value);
163
- if (recorded !== undefined && !recorded.ok)
164
- return toCallToolResult(recorded, contract);
165
- }
166
- return toCallToolResult(result, contract);
160
+ if (!result.ok)
161
+ return toCallToolResult(result, contract);
162
+ return toEvidenceToolResult(result.value, contract, registration.recordEvidence?.(result.value));
167
163
  };
168
164
  const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
169
- const recordWorkflowUnknowns = ({ name, result, evidenceId, recordUnknown, }) => {
170
- if (!["trace_feature", "trace_call_path", "inspect_native_api"].includes(name) ||
171
- recordUnknown === undefined ||
172
- typeof result !== "object" ||
173
- result === null ||
174
- Array.isArray(result) ||
175
- !Array.isArray(result.residual_unknowns))
176
- return { ok: true, value: null };
177
- for (const question of result.residual_unknowns) {
178
- if (typeof question !== "string")
179
- continue;
180
- const recorded = recordUnknown({
181
- question,
182
- severity: "medium",
183
- domain: name === "inspect_native_api" ? "native-api" : "control-flow",
184
- supporting_evidence_ids: [evidenceId],
185
- contradicting_evidence_ids: [],
186
- required_authority: "shipped-artifact",
187
- required_confidence: "observed",
188
- required_environment: null,
189
- recommended_probes: [
190
- {
191
- operation: name,
192
- rationale: name === "inspect_native_api"
193
- ? "Confirm the unsupported boundary with a capable provider or ABI probe."
194
- : "Continue with a focused query or another available provider.",
195
- },
196
- ],
197
- relationships: [],
198
- });
199
- if (!recorded.ok &&
200
- !(recorded.error instanceof UnknownRegistryError &&
201
- recorded.error.reason === "already-exists"))
202
- return recorded;
203
- }
204
- return { ok: true, value: null };
205
- };
@@ -3,7 +3,7 @@ import { jsonObjectSchema } from "../domain/jsonValue.js";
3
3
  import { mcpProgressReporter } from "./mcpProgress.js";
4
4
  import { logToolExecution } from "./toolLogging.js";
5
5
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
6
- import { toCallToolResult } from "./toolResult.js";
6
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
7
7
  import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
8
8
  /** Register provider-backed contracts that return atomic Evidence observations. */
9
9
  export const registerEvidenceTools = (server, analysis, contracts, options) => {
@@ -55,9 +55,7 @@ export const registerEvidenceTools = (server, analysis, contracts, options) => {
55
55
  return toCallToolResult(sourceRecorded, contract);
56
56
  }
57
57
  const recorded = options.recordEvidence?.(evidence);
58
- return recorded !== undefined && !recorded.ok
59
- ? toCallToolResult(recorded, contract)
60
- : toCallToolResult({ ok: true, value: evidence }, contract);
58
+ return toEvidenceToolResult(evidence, contract, recorded);
61
59
  });
62
60
  }
63
61
  };
@@ -1,7 +1,7 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
2
  import { logToolExecution } from "./toolLogging.js";
3
3
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
4
- import { toCallToolResult } from "./toolResult.js";
4
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
5
5
  /** Bind the named EVM contract to shared validation and session Evidence recording. */
6
6
  export const registerEvmTools = (server, service, logger, recordEvidence) => {
7
7
  const contract = toolContract("inspect_evm_interface");
@@ -10,8 +10,6 @@ export const registerEvmTools = (server, service, logger, recordEvidence) => {
10
10
  if (!result.ok)
11
11
  return toCallToolResult(result, contract);
12
12
  const recorded = recordEvidence?.(result.value);
13
- return recorded !== undefined && !recorded.ok
14
- ? toCallToolResult(recorded, contract)
15
- : toCallToolResult(result, contract);
13
+ return toEvidenceToolResult(result.value, contract, recorded);
16
14
  });
17
15
  };
@@ -1,7 +1,7 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
2
  import { logToolExecution } from "./toolLogging.js";
3
3
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
4
- import { toCallToolResult } from "./toolResult.js";
4
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
5
5
  /** Bind firmware handlers to their exact named schemas. */
6
6
  export const registerFirmwareTools = (server, service, logger, recordEvidence) => {
7
7
  const handler = (contract) => async (input, context) => {
@@ -11,9 +11,7 @@ export const registerFirmwareTools = (server, service, logger, recordEvidence) =
11
11
  if (!result.ok)
12
12
  return toCallToolResult(result, contract);
13
13
  const recorded = recordEvidence?.(result.value);
14
- return recorded !== undefined && !recorded.ok
15
- ? toCallToolResult(recorded, contract)
16
- : toCallToolResult(result, contract);
14
+ return toEvidenceToolResult(result.value, contract, recorded);
17
15
  };
18
16
  const inspect = toolContract("inspect_firmware_regions");
19
17
  server.registerTool(inspect.name, toolRegistrationOptions(inspect), handler(inspect));
@@ -9,7 +9,7 @@ import { recordSessionEvidenceSources } from "./sessionEvidence.js";
9
9
  import { runDerivedOperation } from "./runDerivedOperation.js";
10
10
  import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
11
11
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { toCallToolResult } from "./toolResult.js";
12
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
13
13
  /** Register explicit Evidence-backed function comparison. */
14
14
  export const registerFunctionComparisonTool = (server, session, contract) => {
15
15
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
@@ -53,19 +53,23 @@ export const registerFunctionComparisonTool = (server, session, contract) => {
53
53
  status: comparison.status,
54
54
  leftIds,
55
55
  rightIds,
56
+ comparisonEvidenceId: evidence.evidence_id,
56
57
  }));
57
- return toCallToolResult(recorded, contract);
58
+ return toEvidenceToolResult(evidence, contract, recorded);
58
59
  });
59
60
  };
60
- const functionUnknownInput = ({ status, leftIds, rightIds, }) => {
61
+ const functionUnknownInput = ({ status, leftIds, rightIds, comparisonEvidenceId, }) => {
61
62
  if (status === "unchanged")
62
63
  return undefined;
64
+ const supportingIds = [...new Set([...leftIds, ...rightIds])];
65
+ const contradictingIds = rightIds.filter((id) => !leftIds.includes(id));
66
+ const contradictory = status === "changed";
63
67
  return {
64
- question: `Function comparison is ${status}`,
68
+ question: `Function comparison is ${status} (comparison ${comparisonEvidenceId})`,
65
69
  severity: status === "changed" ? "medium" : "high",
66
70
  domain: "function-comparison",
67
- supporting_evidence_ids: [...leftIds],
68
- contradicting_evidence_ids: [...rightIds],
71
+ supporting_evidence_ids: contradictory ? [...leftIds] : supportingIds,
72
+ contradicting_evidence_ids: contradictory ? contradictingIds : [],
69
73
  required_authority: "shipped-artifact",
70
74
  required_confidence: "observed",
71
75
  required_environment: null,
@@ -9,7 +9,7 @@ import { comparisonClosure, evidenceClosure, functionEvidenceIds, isIncomplete,
9
9
  import { runDerivedOperation } from "./runDerivedOperation.js";
10
10
  import { CALL_PATH_PROVIDER, CHANGED_BEHAVIOR_PROVIDER, RECONSTRUCTION_PROVIDER, STATIC_RUNTIME_PROVIDER, } from "./sessionToolPolicies.js";
11
11
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { toCallToolResult } from "./toolResult.js";
12
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
13
13
  /** Register Evidence-composed differential investigation workflows. */
14
14
  export const registerInvestigationTools = (server, session) => {
15
15
  registerChangedBehavior(server, session, toolContract("find_changed_behavior"));
@@ -51,7 +51,7 @@ const registerChangedBehavior = (server, session, contract) => {
51
51
  },
52
52
  ],
53
53
  });
54
- return toCallToolResult(recorded, contract);
54
+ return toEvidenceToolResult(evidence, contract, recorded);
55
55
  });
56
56
  };
57
57
  const registerCallPath = (server, session, contract) => {
@@ -89,7 +89,7 @@ const registerCallPath = (server, session, contract) => {
89
89
  },
90
90
  ],
91
91
  });
92
- return toCallToolResult(recorded, contract);
92
+ return toEvidenceToolResult(evidence, contract, recorded);
93
93
  });
94
94
  };
95
95
  const registerStaticRuntime = (server, session, contract) => {
@@ -117,7 +117,7 @@ const registerStaticRuntime = (server, session, contract) => {
117
117
  limitations: result.limitations,
118
118
  evidenceLinks: links,
119
119
  });
120
- return toCallToolResult(recordWorkflowEvidence(session, evidence, result.status === "unknown" || result.status === "truncated", {
120
+ return toEvidenceToolResult(evidence, contract, recordWorkflowEvidence(session, evidence, result.status === "unknown" || result.status === "truncated", {
121
121
  question: "Does runtime behavior match the available static analysis?",
122
122
  domain: "static-runtime-correlation",
123
123
  requiredAuthority: null,
@@ -128,7 +128,7 @@ const registerStaticRuntime = (server, session, contract) => {
128
128
  rationale: "Repeat runtime observations and complete the mapped static comparison Evidence.",
129
129
  },
130
130
  ],
131
- }), contract);
131
+ }));
132
132
  });
133
133
  };
134
134
  const registerReconstruction = (server, session, contract) => {
@@ -155,7 +155,7 @@ const registerReconstruction = (server, session, contract) => {
155
155
  limitations: result.limitations,
156
156
  evidenceLinks: links,
157
157
  });
158
- return toCallToolResult(recordWorkflowEvidence(session, evidence, result.status === "unknown", {
158
+ return toEvidenceToolResult(evidence, contract, recordWorkflowEvidence(session, evidence, result.status === "unknown", {
159
159
  question: "Does the reconstruction satisfy every declared claim?",
160
160
  domain: "reconstruction-verification",
161
161
  requiredAuthority: null,
@@ -164,6 +164,6 @@ const registerReconstruction = (server, session, contract) => {
164
164
  operation,
165
165
  rationale,
166
166
  })),
167
- }), contract);
167
+ }));
168
168
  });
169
169
  };
@@ -1,7 +1,7 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
2
  import { logToolExecution } from "./toolLogging.js";
3
3
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
4
- import { toCallToolResult } from "./toolResult.js";
4
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
5
5
  /** Bind optional recovery to its exact named contract without acquiring an engine. */
6
6
  export const registerJavaScriptRecoveryTool = (server, service, logger, recordEvidence) => {
7
7
  const contract = toolContract("recover_javascript_sources");
@@ -10,8 +10,6 @@ export const registerJavaScriptRecoveryTool = (server, service, logger, recordEv
10
10
  if (!result.ok)
11
11
  return toCallToolResult(result, contract);
12
12
  const recorded = recordEvidence?.(result.value);
13
- return recorded !== undefined && !recorded.ok
14
- ? toCallToolResult(recorded, contract)
15
- : toCallToolResult(result, contract);
13
+ return toEvidenceToolResult(result.value, contract, recorded);
16
14
  });
17
15
  };
@@ -5,7 +5,7 @@ import { toolContract } from "../contracts/toolContracts.js";
5
5
  import { observeJavaScriptRuntimeInputSchema } from "../domain/javascript/javascriptRuntimeObservation.js";
6
6
  import { logToolExecution } from "./toolLogging.js";
7
7
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
8
- import { toCallToolResult } from "./toolResult.js";
8
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
9
9
  /** Register passive Inspector tools even when policy keeps them unavailable. */
10
10
  export const registerJavaScriptRuntimeObservationTools = (server, options) => {
11
11
  const listContract = toolContract("list_javascript_runtime_targets");
@@ -24,7 +24,5 @@ const runRuntimeTool = async (options, contract, request, execute) => {
24
24
  if (!result.ok)
25
25
  return toCallToolResult(result, contract);
26
26
  const recorded = options.recordEvidence?.(result.value);
27
- return recorded !== undefined && !recorded.ok
28
- ? toCallToolResult(recorded, contract)
29
- : toCallToolResult({ ok: true, value: result.value }, contract);
27
+ return toEvidenceToolResult(result.value, contract, recorded);
30
28
  };
@@ -3,7 +3,7 @@ import { compareManagedMembersEvidenceValidated } from "../../application/manage
3
3
  import { managedMemberComparisonResultSchema } from "../../domain/managed/managedMemberComparison.js";
4
4
  import { logToolExecution } from "../toolLogging.js";
5
5
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
6
- import { toCallToolResult } from "../toolResult.js";
6
+ import { toCallToolResult, toEvidenceToolResult } from "../toolResult.js";
7
7
  import { managedWorkflowContract } from "./contract.js";
8
8
  import { resolveManagedEvidence } from "./evidence.js";
9
9
  const compareContract = managedWorkflowContract("compare_managed_members");
@@ -51,8 +51,6 @@ export const registerCompareManagedMembers = (server, options) => {
51
51
  relationships: [],
52
52
  })
53
53
  : options.recordEvidence?.(result.value);
54
- if (output !== undefined && !output.ok)
55
- return toCallToolResult(output, compareContract);
56
- return toCallToolResult({ ok: true, value: result.value }, compareContract);
54
+ return toEvidenceToolResult(result.value, compareContract, output);
57
55
  });
58
56
  };
@@ -1,7 +1,7 @@
1
1
  import { importManagedReconstructionEvidenceValidated } from "../../application/managed/ManagedReconstructionService.js";
2
2
  import { logToolExecution } from "../toolLogging.js";
3
3
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
4
- import { toCallToolResult } from "../toolResult.js";
4
+ import { toCallToolResult, toEvidenceToolResult } from "../toolResult.js";
5
5
  import { managedWorkflowContract } from "./contract.js";
6
6
  import { resolveManagedEvidence } from "./evidence.js";
7
7
  const reconstructionContract = managedWorkflowContract("import_managed_reconstruction");
@@ -22,8 +22,6 @@ export const registerImportManagedReconstruction = (server, options) => {
22
22
  if (recordedSource !== undefined && !recordedSource.ok)
23
23
  return toCallToolResult(recordedSource, reconstructionContract);
24
24
  const recorded = options.recordEvidence?.(result.value);
25
- if (recorded !== undefined && !recorded.ok)
26
- return toCallToolResult(recorded, reconstructionContract);
27
- return toCallToolResult(result, reconstructionContract);
25
+ return toEvidenceToolResult(result.value, reconstructionContract, recorded);
28
26
  });
29
27
  };
@@ -2,7 +2,7 @@ import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
2
  import { projectManagedApplicationGraphEvidence } from "../../application/managed/ManagedApplicationGraphService.js";
3
3
  import { logToolExecution } from "../toolLogging.js";
4
4
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
5
- import { toCallToolResult } from "../toolResult.js";
5
+ import { toCallToolResult, toEvidenceToolResult } from "../toolResult.js";
6
6
  import { managedWorkflowContract } from "./contract.js";
7
7
  import { resolveManagedArtifactEvidence, resolveManagedBoundaryEvidence, resolveManagedEvidence, sourceEvidence, } from "./evidence.js";
8
8
  const graphContract = managedWorkflowContract("project_managed_application_graph");
@@ -36,8 +36,6 @@ export const registerProjectManagedApplicationGraph = (server, options) => {
36
36
  if (!recordedSources.ok)
37
37
  return toCallToolResult(recordedSources, graphContract);
38
38
  const recorded = options.recordEvidence?.(result.value);
39
- if (recorded !== undefined && !recorded.ok)
40
- return toCallToolResult(recorded, graphContract);
41
- return toCallToolResult(result, graphContract);
39
+ return toEvidenceToolResult(result.value, graphContract, recorded);
42
40
  });
43
41
  };
@@ -3,7 +3,7 @@ import { verifyManagedNativeBoundariesEvidence } from "../../application/managed
3
3
  import { managedNativeVerificationResultSchema } from "../../domain/managed/managedNativeVerification.js";
4
4
  import { logToolExecution } from "../toolLogging.js";
5
5
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
6
- import { toCallToolResult } from "../toolResult.js";
6
+ import { toCallToolResult, toEvidenceToolResult } from "../toolResult.js";
7
7
  import { managedWorkflowContract } from "./contract.js";
8
8
  import { resolveManagedBoundaryEvidence, resolveNativeEvidence, } from "./evidence.js";
9
9
  const nativeVerificationContract = managedWorkflowContract("verify_managed_native_boundaries");
@@ -57,8 +57,6 @@ export const registerVerifyManagedNativeBoundaries = (server, options) => {
57
57
  relationships: [],
58
58
  })
59
59
  : options.recordEvidence?.(result.value);
60
- if (output !== undefined && !output.ok)
61
- return toCallToolResult(output, nativeVerificationContract);
62
- return toCallToolResult(result, nativeVerificationContract);
60
+ return toEvidenceToolResult(result.value, nativeVerificationContract, output);
63
61
  });
64
62
  };
@@ -5,7 +5,7 @@ import { jsonObjectSchema, jsonValueSchema, } from "../domain/jsonValue.js";
5
5
  import { mcpProgressReporter } from "./mcpProgress.js";
6
6
  import { logToolExecution } from "./toolLogging.js";
7
7
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
8
- import { toCallToolResult } from "./toolResult.js";
8
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
9
9
  /** Register direct bridge proxies, preserving MCP cancellation and typed errors. */
10
10
  export const registerOfficialTools = (server, analysis, options) => {
11
11
  for (const contract of OFFICIAL_TOOL_CONTRACTS) {
@@ -40,9 +40,7 @@ const registerOfficialTool = (server, analysis, contract, registration) => {
40
40
  locations: result.value.locations,
41
41
  });
42
42
  const recorded = registration.recordEvidence?.(evidence);
43
- if (recorded !== undefined && !recorded.ok)
44
- return toCallToolResult(recorded, contract);
45
- return toCallToolResult({ ok: true, value: evidence }, contract);
43
+ return toEvidenceToolResult(evidence, contract, recorded);
46
44
  });
47
45
  };
48
46
  const runOfficialOperation = async (analysis, contract, arguments_, execution) => {
@@ -1,61 +1,83 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
+ import { AnalysisInputError } from "../domain/analysisErrorCore.js";
3
+ import {} from "../domain/analysisErrorBase.js";
4
+ import { describeValidationFailure } from "../domain/evidenceBundle.js";
2
5
  import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
3
6
  import { createEvidence, parseEvidence, } from "../domain/evidence.js";
4
7
  import { jsonValueSchema } from "../domain/jsonValue.js";
5
8
  import { compareProcessCaptures, parseProcessCapture, } from "../domain/process/processCapture.js";
6
- import { err } from "../domain/result.js";
9
+ import { err, ok } from "../domain/result.js";
7
10
  import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
8
11
  import { recordSessionEvidenceSources } from "./sessionEvidence.js";
9
12
  import { runDerivedOperation } from "./runDerivedOperation.js";
10
13
  import { PROCESS_PROVIDER } from "./sessionToolPolicies.js";
11
14
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { toCallToolResult } from "./toolResult.js";
15
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
13
16
  const PROCESS_CAPTURE_EVIDENCE = {
14
17
  operation: "capture_process_scenario",
15
18
  predicate: "rea.process-capture",
16
19
  };
17
20
  const sourceLocations = (left, right) => [...(left ?? []), ...(right ?? [])];
21
+ /**
22
+ * Parse one side and name the failed constraint: tampered Evidence, Evidence
23
+ * from another workflow, or an invalid capture result.
24
+ */
25
+ const parseCaptureSide = (operation, side, value) => {
26
+ let record;
27
+ try {
28
+ record = parseEvidence(value);
29
+ }
30
+ catch (cause) {
31
+ return err(new EvidenceIntegrityError(`${side} Evidence failed validation`, {
32
+ cause,
33
+ userMessage: `The ${side} Evidence failed validation (${describeValidationFailure(cause)}). Supply unmodified capture Evidence from capture_process_scenario.`,
34
+ }));
35
+ }
36
+ if (record.operation !== PROCESS_CAPTURE_EVIDENCE.operation ||
37
+ record.predicate_type !== PROCESS_CAPTURE_EVIDENCE.predicate)
38
+ return err(new AnalysisInputError(operation, undefined, [
39
+ {
40
+ path: [side],
41
+ reason: "invalid_value",
42
+ message: `Expected process capture Evidence (operation ${PROCESS_CAPTURE_EVIDENCE.operation}, predicate ${PROCESS_CAPTURE_EVIDENCE.predicate}); the ${side} Evidence has operation ${record.operation} and predicate ${record.predicate_type}.`,
43
+ },
44
+ ]));
45
+ try {
46
+ return ok({
47
+ record,
48
+ capture: parseProcessCapture(record.normalized_result),
49
+ });
50
+ }
51
+ catch (cause) {
52
+ return err(new EvidenceIntegrityError(`${side} process capture failed validation`, {
53
+ cause,
54
+ userMessage: `The ${side} Evidence has an invalid process capture result (${describeValidationFailure(cause)}). Recreate the capture with capture_process_scenario.`,
55
+ }));
56
+ }
57
+ };
18
58
  /** Register deterministic process-capture comparison and contradiction tracking. */
19
59
  export const registerProcessComparisonTool = (server, session, contract, now = Date.now) => {
20
60
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
21
- let leftRecord;
22
- let rightRecord;
23
- try {
24
- leftRecord = parseEvidence(input.left);
25
- rightRecord = parseEvidence(input.right);
26
- if (leftRecord.operation !== PROCESS_CAPTURE_EVIDENCE.operation ||
27
- rightRecord.operation !== PROCESS_CAPTURE_EVIDENCE.operation ||
28
- leftRecord.predicate_type !== PROCESS_CAPTURE_EVIDENCE.predicate ||
29
- rightRecord.predicate_type !== PROCESS_CAPTURE_EVIDENCE.predicate)
30
- throw new TypeError("Expected process capture Evidence");
31
- }
32
- catch (cause) {
33
- return toCallToolResult(err(new EvidenceIntegrityError(cause instanceof Error ? cause.message : "Invalid Evidence")), contract);
34
- }
35
- let comparison;
36
- let leftCapture;
37
- let rightCapture;
38
- try {
39
- leftCapture = parseProcessCapture(leftRecord.normalized_result);
40
- rightCapture = parseProcessCapture(rightRecord.normalized_result);
41
- const computed = await runDerivedOperation(context, contract.name, () => compareProcessCaptures(leftCapture, rightCapture, {
42
- ...(input.max_capture_age_ms === undefined
43
- ? {}
44
- : { maxCaptureAgeMs: input.max_capture_age_ms }),
45
- ...(input.trace_spec === undefined
46
- ? {}
47
- : { traceSpecification: input.trace_spec }),
48
- now,
49
- }));
50
- if (!computed.ok)
51
- return toCallToolResult(computed, contract);
52
- comparison = computed.value;
53
- }
54
- catch (cause) {
55
- return toCallToolResult(err(new EvidenceIntegrityError(cause instanceof Error
56
- ? cause.message
57
- : "Invalid process capture")), contract);
58
- }
61
+ const left = parseCaptureSide(contract.name, "left", input.left);
62
+ if (!left.ok)
63
+ return toCallToolResult(left, contract);
64
+ const right = parseCaptureSide(contract.name, "right", input.right);
65
+ if (!right.ok)
66
+ return toCallToolResult(right, contract);
67
+ const { record: leftRecord, capture: leftCapture } = left.value;
68
+ const { record: rightRecord, capture: rightCapture } = right.value;
69
+ const computed = await runDerivedOperation(context, contract.name, () => compareProcessCaptures(leftCapture, rightCapture, {
70
+ ...(input.max_capture_age_ms === undefined
71
+ ? {}
72
+ : { maxCaptureAgeMs: input.max_capture_age_ms }),
73
+ ...(input.trace_spec === undefined
74
+ ? {}
75
+ : { traceSpecification: input.trace_spec }),
76
+ now,
77
+ }));
78
+ if (!computed.ok)
79
+ return toCallToolResult(computed, contract);
80
+ const comparison = computed.value;
59
81
  const evidence = createEvidence(undefined, PROCESS_PROVIDER, {
60
82
  predicateType: "rea.process-comparison",
61
83
  operation: contract.name,
@@ -78,11 +100,11 @@ export const registerProcessComparisonTool = (server, session, contract, now = D
78
100
  const recordedSources = recordSessionEvidenceSources((evidence) => session.recordEvidence(evidence), [leftRecord, rightRecord]);
79
101
  if (!recordedSources.ok)
80
102
  return toCallToolResult(recordedSources, contract);
81
- return toCallToolResult(recordDerivedEvidence(session, evidence, comparisonUnknownInput({
103
+ return toEvidenceToolResult(evidence, contract, recordDerivedEvidence(session, evidence, comparisonUnknownInput({
82
104
  left_evidence_id: leftRecord.evidence_id,
83
105
  right_evidence_id: rightRecord.evidence_id,
84
106
  comparison_evidence_id: evidence.evidence_id,
85
- }, comparison)), contract);
107
+ }, comparison)));
86
108
  });
87
109
  };
88
110
  const comparisonUnknownInput = (parsed, comparison) => {
@@ -98,14 +120,18 @@ const comparisonUnknownInput = (parsed, comparison) => {
98
120
  .filter(([, status]) => status !== "unchanged")
99
121
  .map(([scope]) => scope)
100
122
  .join(", ");
123
+ const contradictory = comparison.status === "changed" &&
124
+ parsed.left_evidence_id !== parsed.right_evidence_id;
101
125
  // Unknown identity uses the question, not its supporting records. Bind the
102
126
  // question to this comparison so distinct capture pairs and policies coexist.
103
127
  return {
104
- question: `Process captures disagree across: ${differingScopes} (comparison ${parsed.comparison_evidence_id})`,
128
+ question: `${contradictory ? "Process captures disagree" : `Process comparison is ${comparison.status}`} across: ${differingScopes} (comparison ${parsed.comparison_evidence_id})`,
105
129
  severity: "high",
106
130
  domain: "process-comparison",
107
- supporting_evidence_ids: [parsed.left_evidence_id],
108
- contradicting_evidence_ids: [parsed.right_evidence_id],
131
+ supporting_evidence_ids: contradictory
132
+ ? [parsed.left_evidence_id]
133
+ : [...new Set([parsed.left_evidence_id, parsed.right_evidence_id])],
134
+ contradicting_evidence_ids: contradictory ? [parsed.right_evidence_id] : [],
109
135
  required_authority: "controlled-replay",
110
136
  required_confidence: "observed",
111
137
  required_environment: null,
@@ -1,7 +1,7 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
2
  import { logToolExecution } from "./toolLogging.js";
3
3
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
4
- import { toCallToolResult } from "./toolResult.js";
4
+ import { toCallToolResult, toEvidenceToolResult } from "./toolResult.js";
5
5
  /** Bind recorded crash inspection to its named contract and session Evidence owner. */
6
6
  export const registerRecordedCrashTools = (server, service, logger, recordEvidence) => {
7
7
  const contract = toolContract("inspect_recorded_crash");
@@ -10,8 +10,6 @@ export const registerRecordedCrashTools = (server, service, logger, recordEviden
10
10
  if (!result.ok)
11
11
  return toCallToolResult(result, contract);
12
12
  const recorded = recordEvidence?.(result.value);
13
- return recorded !== undefined && !recorded.ok
14
- ? toCallToolResult(recorded, contract)
15
- : toCallToolResult(result, contract);
13
+ return toEvidenceToolResult(result.value, contract, recorded);
16
14
  });
17
15
  };
@@ -11,7 +11,7 @@ export const registerEvidenceTools = (registration) => {
11
11
  };
12
12
  const registerExportEvidenceTool = ({ server, session, exportContract, }) => {
13
13
  server.registerTool(exportContract.name, toolRegistrationOptions(exportContract), async (input) => {
14
- const bundle = session.exportEvidenceBundle();
14
+ const bundle = bundleForSerialization(session);
15
15
  const written = await writeEvidenceBundle(bundle, input.path, input.overwrite);
16
16
  return written.ok
17
17
  ? toCallToolResult(ok({
@@ -24,7 +24,7 @@ const registerExportEvidenceTool = ({ server, session, exportContract, }) => {
24
24
  });
25
25
  };
26
26
  const registerSnapshotEvidenceTool = ({ server, session, snapshotContract, }) => {
27
- server.registerTool(snapshotContract.name, toolRegistrationOptions(snapshotContract), () => toCallToolResult(ok(session.exportEvidenceBundle()), snapshotContract));
27
+ server.registerTool(snapshotContract.name, toolRegistrationOptions(snapshotContract), () => toCallToolResult(ok(bundleForSerialization(session)), snapshotContract));
28
28
  };
29
29
  const registerImportEvidenceTool = ({ server, session, importContract, }) => {
30
30
  server.registerTool(importContract.name, toolRegistrationOptions(importContract), async (input) => {
@@ -32,19 +32,18 @@ const registerImportEvidenceTool = ({ server, session, importContract, }) => {
32
32
  const loaded = await readEvidenceBundle(path);
33
33
  if (!loaded.ok)
34
34
  return toCallToolResult(loaded, importContract);
35
- const retainedUnknownRevisions = new Set(session
36
- .exportEvidenceBundle()
37
- .unknowns.map((unknown) => unknownRevisionKey(unknown)));
35
+ const retainedUnknownRevisions = new Set(bundleForSerialization(session).unknowns.map((unknown) => unknownRevisionKey(unknown)));
38
36
  const imported = session.importEvidenceBundle(loaded.value);
39
37
  return imported.ok
40
38
  ? toCallToolResult(ok({
41
39
  imported: imported.value,
42
40
  unknowns_added: loaded.value.unknowns.filter((unknown) => !retainedUnknownRevisions.has(unknownRevisionKey(unknown))).length,
43
- total: session.exportEvidenceBundle().records.length,
41
+ total: bundleForSerialization(session).records.length,
44
42
  }), importContract)
45
43
  : toCallToolResult(imported, importContract);
46
44
  });
47
45
  };
46
+ const bundleForSerialization = (session) => session.evidenceBundleForSerialization?.() ?? session.exportEvidenceBundle();
48
47
  const unknownRevisionKey = (unknown) => `${unknown.unknown_id}:${String(unknown.revision)}`;
49
48
  /** Register residual-unknown query and mutation tools. */
50
49
  const registerListUnknownsTool = ({ server, session, }) => {