rea-agents 1.7.0 → 2.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 (333) hide show
  1. package/README.md +112 -59
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +42 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +11 -29
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +165 -197
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +112 -0
  26. package/dist/application/ElectronBoundaryGraph.js +9 -0
  27. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  28. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  29. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  30. package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
  31. package/dist/application/EnhancedToolPagination.js +22 -0
  32. package/dist/application/EnhancedToolTypes.js +4 -0
  33. package/dist/application/EnhancedTools.js +58 -50
  34. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  35. package/dist/application/InvestigationProviders.js +30 -0
  36. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  37. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  38. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  39. package/dist/application/JavaScriptApplicationService.js +74 -0
  40. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  41. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  42. package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
  43. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  44. package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
  45. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  46. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  47. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  48. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  49. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  50. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  51. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  52. package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
  53. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  54. package/dist/application/JavaScriptJsonModules.js +39 -0
  55. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  56. package/dist/application/JavaScriptReplayPermission.js +16 -0
  57. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  58. package/dist/application/JavaScriptReplayService.js +292 -0
  59. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  60. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  61. package/dist/application/LinuxHopper.js +10 -0
  62. package/dist/application/MacHopper.js +22 -11
  63. package/dist/application/ManagedApplicationGraphService.js +55 -0
  64. package/dist/application/ManagedMemberComparisonService.js +122 -0
  65. package/dist/application/ManagedNativeVerificationService.js +39 -0
  66. package/dist/application/ManagedReconstructionService.js +58 -0
  67. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  68. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  69. package/dist/application/PermissionAuthority.js +106 -63
  70. package/dist/application/ProcessCaptureCapability.js +1 -1
  71. package/dist/application/ProcessCapturePermission.js +13 -0
  72. package/dist/application/ProcessCli.js +2 -12
  73. package/dist/application/ProcessHarness.js +1 -1
  74. package/dist/application/ProcessSampling.js +15 -11
  75. package/dist/application/ProjectPermissionStore.js +49 -9
  76. package/dist/application/RealHopperAssertions.js +76 -0
  77. package/dist/application/ReconstructionCoverageService.js +69 -0
  78. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  79. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  80. package/dist/application/Setup.js +147 -259
  81. package/dist/application/SetupClientConfiguration.js +220 -0
  82. package/dist/application/SetupClients.js +24 -2
  83. package/dist/application/SetupPlan.js +123 -12
  84. package/dist/application/SetupSkill.js +26 -12
  85. package/dist/application/SupportedClients.js +1 -0
  86. package/dist/application/Uninstall.js +6 -3
  87. package/dist/application/WindowsCapabilities.js +86 -0
  88. package/dist/application/runtime.js +2 -0
  89. package/dist/artifacts/AsarArtifactReader.js +11 -0
  90. package/dist/browser/BrowserProcessStartup.js +88 -0
  91. package/dist/browser/CdpCaptureDocuments.js +12 -8
  92. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  93. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  94. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  95. package/dist/browser/CdpCaptureEventState.js +1 -0
  96. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  97. package/dist/browser/CdpCaptureEvents.js +46 -464
  98. package/dist/browser/CdpElectronInspection.js +106 -162
  99. package/dist/browser/CdpElectronProvider.js +5 -1
  100. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  101. package/dist/browser/CdpElectronScripts.js +94 -0
  102. package/dist/browser/CdpElectronWorkers.js +56 -0
  103. package/dist/browser/CdpObservationSession.js +51 -8
  104. package/dist/browser/CdpPageCapture.js +12 -129
  105. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  106. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  107. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  108. package/dist/browser/PngVisualDiff.js +9 -2
  109. package/dist/catalogIdentity.js +8 -1
  110. package/dist/cli/artifactCommands.js +82 -0
  111. package/dist/cli/coreAnalysisCommands.js +232 -0
  112. package/dist/cli/managedCommands.js +397 -0
  113. package/dist/cli/managedProjectGraphCommand.js +24 -0
  114. package/dist/cli/options.js +9 -0
  115. package/dist/cli/setupCommands.js +108 -0
  116. package/dist/cli/types.js +1 -0
  117. package/dist/cli/utilityCommands.js +122 -0
  118. package/dist/cli.js +13 -383
  119. package/dist/cliApplicationCommands.js +176 -0
  120. package/dist/cliBrowserAdvancedCommands.js +73 -16
  121. package/dist/cliBrowserCommands.js +39 -115
  122. package/dist/cliCommandNames.js +17 -0
  123. package/dist/cliElectronCommands.js +100 -27
  124. package/dist/cliEvidenceCommands.js +13 -2
  125. package/dist/cliInvestigationCommands.js +53 -10
  126. package/dist/cliJsonInput.js +54 -0
  127. package/dist/cliObservationOptions.js +137 -0
  128. package/dist/cliPolicyCommands.js +80 -46
  129. package/dist/cliSetup.js +289 -0
  130. package/dist/config/environment.js +107 -0
  131. package/dist/config/parseConfig.js +228 -0
  132. package/dist/config/parsers.js +68 -0
  133. package/dist/config/permissions.js +30 -0
  134. package/dist/config/types.js +1 -0
  135. package/dist/config.js +1 -292
  136. package/dist/contracts/applicationToolContracts.js +225 -0
  137. package/dist/contracts/artifactToolContracts.js +5 -9
  138. package/dist/contracts/browserToolContracts.js +14 -62
  139. package/dist/contracts/electronToolContracts.js +45 -19
  140. package/dist/contracts/errorSchemas.js +1 -0
  141. package/dist/contracts/investigationExamples.js +0 -6
  142. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  143. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  144. package/dist/contracts/managedToolContracts.js +153 -0
  145. package/dist/contracts/managedWorkflowExamples.js +346 -0
  146. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  147. package/dist/contracts/nativeToolContracts.js +2 -6
  148. package/dist/contracts/promptContracts.js +18 -2
  149. package/dist/contracts/providerSelection.js +2 -0
  150. package/dist/contracts/toolContractExamples.js +10 -25
  151. package/dist/contracts/toolContracts.js +49 -47
  152. package/dist/contracts/toolEffects.js +174 -0
  153. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  154. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  155. package/dist/contracts/toolOutputSchemas.js +2 -535
  156. package/dist/doctorRuntime.js +42 -1
  157. package/dist/domain/analysisErrorPresentation.js +234 -0
  158. package/dist/domain/analysisErrorProjection.js +284 -0
  159. package/dist/domain/artifactComparison.js +37 -19
  160. package/dist/domain/binaryTarget.js +87 -37
  161. package/dist/domain/browserObservation.js +1 -282
  162. package/dist/domain/browserObservationSchemas.js +286 -0
  163. package/dist/domain/bundleComparison.js +4 -4
  164. package/dist/domain/electronObservation.js +13 -0
  165. package/dist/domain/electronStaticAnalysis.js +9 -0
  166. package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
  167. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  168. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  169. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  170. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  171. package/dist/domain/errors.js +32 -448
  172. package/dist/domain/functionComparison.js +4 -165
  173. package/dist/domain/functionComparisonDimensions.js +164 -0
  174. package/dist/domain/functionComparisonSchemas.js +3 -8
  175. package/dist/domain/inputIssueProjection.js +52 -0
  176. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  177. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  178. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  179. package/dist/domain/javascriptApplicationGraph.js +2 -1
  180. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  181. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  182. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  183. package/dist/domain/javascriptApplicationVersionItems.js +233 -0
  184. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  185. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  186. package/dist/domain/javascriptFeatureSeed.js +140 -0
  187. package/dist/domain/javascriptFeatureTrace.js +232 -0
  188. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  189. package/dist/domain/javascriptFeatureTraversal.js +100 -0
  190. package/dist/domain/javascriptNativeHandoff.js +85 -0
  191. package/dist/domain/javascriptReplay.js +361 -0
  192. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  193. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  194. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  195. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  196. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  197. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  198. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  199. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  200. package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
  201. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  202. package/dist/domain/javascriptSemanticIr.js +30 -0
  203. package/dist/domain/javascriptSemanticProjection.js +366 -0
  204. package/dist/domain/javascriptSemanticState.js +40 -0
  205. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  206. package/dist/domain/javascriptSemanticValues.js +352 -0
  207. package/dist/domain/javascriptStaticAnalysis.js +26 -254
  208. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  209. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  210. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  211. package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
  212. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  213. package/dist/domain/knownPageCoverage.js +21 -0
  214. package/dist/domain/managedApplicationGraph.js +206 -0
  215. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  216. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  217. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  218. package/dist/domain/managedArtifact.js +452 -0
  219. package/dist/domain/managedMemberComparison.js +211 -0
  220. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  221. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  222. package/dist/domain/managedNativeVerification.js +46 -0
  223. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  224. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  225. package/dist/domain/managedReconstruction.js +196 -0
  226. package/dist/domain/managedRuntimeCorrelation.js +184 -0
  227. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  228. package/dist/domain/permissionPolicy.js +2 -0
  229. package/dist/domain/reconstructionCoverage.js +387 -0
  230. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  231. package/dist/domain/reconstructionVerificationSchemas.js +9 -3
  232. package/dist/domain/runtimeCharacterization.js +85 -0
  233. package/dist/domain/webBundleAnalyzer.js +3 -409
  234. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  235. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  236. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  237. package/dist/dotnet/ManagedArtifactInspector.js +339 -0
  238. package/dist/dotnet/ManagedMemberInspector.js +153 -0
  239. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  240. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  241. package/dist/dotnet/ManagedMemberRows.js +120 -0
  242. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  243. package/dist/dotnet/ManagedMetadataInventory.js +104 -0
  244. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  245. package/dist/dotnet/ManagedMetadataLayout.js +259 -0
  246. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  247. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  248. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  249. package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
  250. package/dist/dotnet/ManagedPeReader.js +188 -0
  251. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  252. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  253. package/dist/generatedPackageMetadata.js +2 -2
  254. package/dist/ghidra/GhidraClient.js +76 -91
  255. package/dist/ghidra/GhidraClientStartup.js +29 -0
  256. package/dist/ghidra/GhidraClientWire.js +34 -0
  257. package/dist/ghidra/GhidraDefaults.js +1 -1
  258. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  259. package/dist/ghidra/GhidraInstallation.js +20 -15
  260. package/dist/ghidra/GhidraLauncher.js +93 -29
  261. package/dist/ghidra/GhidraProvider.js +67 -161
  262. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  263. package/dist/ghidra/GhidraSessionValues.js +2 -0
  264. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  265. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  266. package/dist/ghidra/GhidraTransport.js +71 -0
  267. package/dist/identity.js +3 -2
  268. package/dist/main/messages.js +5 -0
  269. package/dist/main/reload.js +49 -0
  270. package/dist/main/shutdown.js +25 -0
  271. package/dist/main/startup.js +14 -0
  272. package/dist/main/state.js +26 -0
  273. package/dist/main/transport.js +61 -0
  274. package/dist/main/types.js +1 -0
  275. package/dist/main.js +35 -132
  276. package/dist/process/PrivateRuntimeRoot.js +3 -2
  277. package/dist/process/ProcessOwnership.js +35 -0
  278. package/dist/process/ProviderProcess.js +2 -0
  279. package/dist/replay/JavaScriptReplayWorker.js +300 -0
  280. package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
  281. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  282. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  283. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  284. package/dist/replay/ReplayOutcome.js +95 -0
  285. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  286. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  287. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  288. package/dist/server/ProcessCaptureElicitation.js +157 -0
  289. package/dist/server/createServer.js +158 -41
  290. package/dist/server/registerApplicationTools/characterization.js +57 -0
  291. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  292. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  293. package/dist/server/registerApplicationTools/coverage.js +84 -0
  294. package/dist/server/registerApplicationTools/helpers.js +42 -0
  295. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  296. package/dist/server/registerApplicationTools/types.js +1 -0
  297. package/dist/server/registerApplicationTools.js +13 -0
  298. package/dist/server/registerArtifactComparisonTool.js +16 -9
  299. package/dist/server/registerBrowserTools.js +61 -60
  300. package/dist/server/registerBundleComparisonTool.js +17 -20
  301. package/dist/server/registerElectronTools.js +39 -12
  302. package/dist/server/registerEnhancedTools.js +52 -15
  303. package/dist/server/registerEvidenceResources.js +54 -0
  304. package/dist/server/registerEvidenceTools.js +5 -1
  305. package/dist/server/registerFunctionComparisonTool.js +14 -7
  306. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  307. package/dist/server/registerInvestigationTools/types.js +1 -0
  308. package/dist/server/registerInvestigationTools.js +103 -132
  309. package/dist/server/registerManagedTools.js +6 -0
  310. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  311. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  312. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  313. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  314. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  315. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  316. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  317. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  318. package/dist/server/registerManagedWorkflowTools.js +13 -0
  319. package/dist/server/registerOfficialTools.js +81 -67
  320. package/dist/server/registerProcessComparisonTool.js +25 -47
  321. package/dist/server/registerSessionRecordTools.js +137 -0
  322. package/dist/server/registerSessionStatusTool.js +9 -8
  323. package/dist/server/registerSessionTools.js +77 -216
  324. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  325. package/dist/server/sessionEvidence.js +14 -19
  326. package/dist/server/toolInputValidation.js +77 -0
  327. package/dist/server/toolRegistrationOptions.js +177 -2
  328. package/dist/server/toolResult.js +30 -17
  329. package/package.json +21 -14
  330. package/scripts/rea.mjs +1 -1
  331. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
  332. package/scripts/prepare-node-pty.mjs +0 -35
  333. package/scripts/rebuild-native.mjs +0 -22
@@ -1,14 +1,15 @@
1
- import { EnhancedTools } from "../application/EnhancedTools.js";
2
- import { enhancedToolNameSchema } from "../contracts/enhancedInputs.js";
1
+ import { EnhancedTools, } from "../application/EnhancedTools.js";
2
+ import { enhancedInputSchemas, enhancedToolNameSchema, } from "../contracts/enhancedInputs.js";
3
3
  import { ENHANCED_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
4
4
  import { toCallToolResult } from "./toolResult.js";
5
5
  import { logToolExecution } from "./toolLogging.js";
6
6
  import { createEvidence } from "../domain/evidence.js";
7
- import { jsonObjectSchema } from "../domain/jsonValue.js";
8
- import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
9
- import { UnknownRegistryError } from "../domain/errors.js";
7
+ import { AnalysisInputError, UnknownRegistryError } from "../domain/errors.js";
8
+ import { ok } from "../domain/result.js";
10
9
  import { mcpProgressReporter } from "./mcpProgress.js";
11
10
  import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
11
+ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
+ import { safeParseToolInput } from "./toolInputValidation.js";
12
13
  /** Register composed workflows against the same port as direct bridge tools. */
13
14
  export const registerEnhancedTools = (server, analysis, options) => {
14
15
  const services = new EnhancedTools(analysis);
@@ -24,12 +25,7 @@ export const registerEnhancedTools = (server, analysis, options) => {
24
25
  };
25
26
  const registerEnhancedTool = (server, services, contract, registration) => {
26
27
  const name = enhancedToolNameSchema.parse(contract.name);
27
- server.registerTool(name, {
28
- description: contract.description,
29
- inputSchema: contract.inputSchema,
30
- outputSchema: contract.outputSchema,
31
- annotations: contract.annotations,
32
- }, async (input, context) => {
28
+ server.registerTool(name, toolRegistrationOptions(contract), async (input, context) => {
33
29
  const progress = mcpProgressReporter(context);
34
30
  await progress.report({
35
31
  phase: name,
@@ -37,9 +33,12 @@ const registerEnhancedTool = (server, services, contract, registration) => {
37
33
  total: 1,
38
34
  message: "started",
39
35
  });
40
- const parsedInput = jsonObjectSchema.parse(enhancedInputSchemas[name].parse(input));
41
- const parameters = { ...parsedInput };
42
- const result = await logToolExecution(registration.logger, name, () => services.execute(name, input, context.mcpReq.signal));
36
+ const validatedCall = parseEnhancedCall(name, input);
37
+ if (!validatedCall.ok)
38
+ return toCallToolResult(validatedCall, contract);
39
+ const parsedInput = validatedCall.value.input;
40
+ const parameters = jsonParameters(parsedInput);
41
+ const result = await logToolExecution(registration.logger, name, () => services.executeValidated(validatedCall.value, context.mcpReq.signal));
43
42
  await progress.report({
44
43
  phase: name,
45
44
  completed: 1,
@@ -68,7 +67,7 @@ const registerEnhancedTool = (server, services, contract, registration) => {
68
67
  return toCallToolResult(recorded, contract);
69
68
  const unknowns = recordWorkflowUnknowns({
70
69
  name,
71
- input: parsedInput,
70
+ input: parameters,
72
71
  result: result.value,
73
72
  evidenceId: evidence.evidence_id,
74
73
  recordUnknown: registration.recordUnknown,
@@ -82,6 +81,44 @@ const registerEnhancedTool = (server, services, contract, registration) => {
82
81
  return toCallToolResult(result, contract);
83
82
  });
84
83
  };
84
+ const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
85
+ const ENHANCED_INPUT_PARSERS = {
86
+ swift_classes: (input) => safeParseToolInput(enhancedInputSchemas.swift_classes, input, "swift_classes"),
87
+ get_objc_classes: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_classes, input, "get_objc_classes"),
88
+ get_objc_protocols: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_protocols, input, "get_objc_protocols"),
89
+ batch_decompile: (input) => safeParseToolInput(enhancedInputSchemas.batch_decompile, input, "batch_decompile"),
90
+ get_call_graph: (input) => safeParseToolInput(enhancedInputSchemas.get_call_graph, input, "get_call_graph"),
91
+ analyze_swift_types: (input) => safeParseToolInput(enhancedInputSchemas.analyze_swift_types, input, "analyze_swift_types"),
92
+ find_xrefs_to_name: (input) => safeParseToolInput(enhancedInputSchemas.find_xrefs_to_name, input, "find_xrefs_to_name"),
93
+ binary_overview: (input) => safeParseToolInput(enhancedInputSchemas.binary_overview, input, "binary_overview"),
94
+ analyze_function: (input) => safeParseToolInput(enhancedInputSchemas.analyze_function, input, "analyze_function"),
95
+ trace_feature: (input) => safeParseToolInput(enhancedInputSchemas.trace_feature, input, "trace_feature"),
96
+ };
97
+ const parseEnhancedCall = (name, input) => {
98
+ switch (name) {
99
+ case "swift_classes":
100
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.swift_classes(input), (value) => ({ name, input: value }));
101
+ case "get_objc_classes":
102
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_classes(input), (value) => ({ name, input: value }));
103
+ case "get_objc_protocols":
104
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_protocols(input), (value) => ({ name, input: value }));
105
+ case "batch_decompile":
106
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.batch_decompile(input), (value) => ({ name, input: value }));
107
+ case "get_call_graph":
108
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_call_graph(input), (value) => ({ name, input: value }));
109
+ case "analyze_swift_types":
110
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_swift_types(input), (value) => ({ name, input: value }));
111
+ case "find_xrefs_to_name":
112
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.find_xrefs_to_name(input), (value) => ({ name, input: value }));
113
+ case "binary_overview":
114
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.binary_overview(input), (value) => ({ name, input: value }));
115
+ case "analyze_function":
116
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_function(input), (value) => ({ name, input: value }));
117
+ case "trace_feature":
118
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.trace_feature(input), (value) => ({ name, input: value }));
119
+ }
120
+ };
121
+ const mapEnhancedCall = (parsed, project) => parsed.ok ? ok(project(parsed.value)) : parsed;
85
122
  const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown, }) => {
86
123
  if (name !== "trace_feature" ||
87
124
  input.unknown_registry_approved !== true ||
@@ -4,6 +4,45 @@ import canonicalize from "canonicalize";
4
4
  const evidenceUri = (evidenceId) => `rea://evidence/${evidenceId}`;
5
5
  /** Expose immutable session-owned Evidence v2 records as MCP resources. */
6
6
  export const registerEvidenceResources = (server, session) => {
7
+ registerReconstructionCoverageResource(server, session);
8
+ registerInvestigationWorkspaceResource(server, session);
9
+ registerSessionEvidenceResource(server, session);
10
+ registerActiveResidualUnknownsResource(server, session);
11
+ registerAnalysisSnapshotResource(server, session);
12
+ registerArtifactPageResource(server, session);
13
+ registerFunctionDossierResource(server, session);
14
+ registerEvidenceSectionResource(server, session);
15
+ registerResidualUnknownResource(server, session);
16
+ };
17
+ const registerReconstructionCoverageResource = (server, session) => {
18
+ server.registerResource("reconstruction-coverage-revision", new ResourceTemplate("rea://reconstruction-coverage/{workspaceId}/revision/{revision}", {
19
+ list: () => ({
20
+ resources: session
21
+ .reconstructionCoverageWorkspaces()
22
+ .map((workspace) => ({
23
+ uri: coverageWorkspaceUri(workspace.workspace_id, workspace.revision),
24
+ name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
25
+ title: `${workspace.name} coverage revision ${String(workspace.revision)}`,
26
+ description: "Immutable evidence-backed reconstruction coverage workspace revision.",
27
+ mimeType: "application/json",
28
+ })),
29
+ }),
30
+ }), {
31
+ title: "Reconstruction coverage revision",
32
+ description: "Canonical CAS-linked surfaces, owners, claims, verifiers, evidence, and completion boundaries.",
33
+ mimeType: "application/json",
34
+ }, (uri, variables) => {
35
+ const workspaceId = stringVariable(variables.workspaceId, uri.href);
36
+ const revisionText = stringVariable(variables.revision, uri.href);
37
+ if (!/^\d+$/u.test(revisionText))
38
+ throw new ResourceNotFoundError(uri.href);
39
+ const workspace = session.reconstructionCoverageWorkspace(workspaceId, Number(revisionText));
40
+ if (workspace === undefined)
41
+ throw new ResourceNotFoundError(uri.href);
42
+ return jsonResource(uri.href, workspace);
43
+ });
44
+ };
45
+ const registerInvestigationWorkspaceResource = (server, session) => {
7
46
  server.registerResource("investigation-workspace-revision", new ResourceTemplate("rea://workspace/{workspaceId}/revision/{revision}", {
8
47
  list: () => ({
9
48
  resources: session.investigationWorkspaces().map((workspace) => ({
@@ -40,6 +79,8 @@ export const registerEvidenceResources = (server, session) => {
40
79
  throw new ResourceNotFoundError(uri.href);
41
80
  return jsonResource(uri.href, workspace);
42
81
  });
82
+ };
83
+ const registerSessionEvidenceResource = (server, session) => {
43
84
  server.registerResource("session-evidence", new ResourceTemplate("rea://evidence/{evidenceId}", {
44
85
  list: () => ({
45
86
  resources: session.exportEvidenceBundle().records.map((evidence) => ({
@@ -77,11 +118,15 @@ export const registerEvidenceResources = (server, session) => {
77
118
  ],
78
119
  };
79
120
  });
121
+ };
122
+ const registerActiveResidualUnknownsResource = (server, session) => {
80
123
  server.registerResource("active-residual-unknowns", "rea://unknowns/active", {
81
124
  title: "Active residual unknowns",
82
125
  description: "Current unresolved session-owned residual unknown heads.",
83
126
  mimeType: "application/json",
84
127
  }, (uri) => jsonResource(uri.href, session.listUnknowns().filter(({ status }) => status !== "resolved")));
128
+ };
129
+ const registerAnalysisSnapshotResource = (server, session) => {
85
130
  server.registerResource("analysis-snapshot", new ResourceTemplate("rea://snapshot/{snapshotDigest}", {
86
131
  list: () => {
87
132
  const snapshot = session.exportAnalysisSnapshot();
@@ -111,6 +156,8 @@ export const registerEvidenceResources = (server, session) => {
111
156
  throw new ResourceNotFoundError(uri.href);
112
157
  return jsonResource(uri.href, snapshot.value);
113
158
  });
159
+ };
160
+ const registerArtifactPageResource = (server, session) => {
114
161
  server.registerResource("artifact-page", new ResourceTemplate("rea://artifact/{manifestId}/{collection}", {
115
162
  list: undefined,
116
163
  complete: {
@@ -143,6 +190,8 @@ export const registerEvidenceResources = (server, session) => {
143
190
  limitations: evidence.limitations,
144
191
  });
145
192
  });
193
+ };
194
+ const registerFunctionDossierResource = (server, session) => {
146
195
  server.registerResource("function-dossier", new ResourceTemplate("rea://function/{targetSha256}/{address}", {
147
196
  list: undefined,
148
197
  }), {
@@ -161,6 +210,8 @@ export const registerEvidenceResources = (server, session) => {
161
210
  throw new ResourceNotFoundError(uri.href);
162
211
  return jsonResource(uri.href, evidence);
163
212
  });
213
+ };
214
+ const registerEvidenceSectionResource = (server, session) => {
164
215
  server.registerResource("evidence-section", new ResourceTemplate("rea://evidence/{evidenceId}/section/{section}", {
165
216
  list: undefined,
166
217
  complete: {
@@ -191,6 +242,8 @@ export const registerEvidenceResources = (server, session) => {
191
242
  value,
192
243
  });
193
244
  });
245
+ };
246
+ const registerResidualUnknownResource = (server, session) => {
194
247
  server.registerResource("residual-unknown", new ResourceTemplate("rea://unknown/{unknownId}", {
195
248
  list: () => ({
196
249
  resources: session.listUnknowns().map((unknown) => ({
@@ -224,6 +277,7 @@ export const registerEvidenceResources = (server, session) => {
224
277
  return jsonResource(uri.href, { current: unknown, history });
225
278
  });
226
279
  };
280
+ const coverageWorkspaceUri = (workspaceId, revision) => `rea://reconstruction-coverage/${workspaceId}/revision/${String(revision)}`;
227
281
  const workspaceUri = (workspaceId, revision) => `rea://workspace/${workspaceId}/revision/${String(revision)}`;
228
282
  const EVIDENCE_SECTIONS = [
229
283
  "result",
@@ -4,6 +4,7 @@ import { logToolExecution } from "./toolLogging.js";
4
4
  import { toCallToolResult } from "./toolResult.js";
5
5
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
6
6
  import { mcpProgressReporter } from "./mcpProgress.js";
7
+ import { safeParseToolInput } from "./toolInputValidation.js";
7
8
  import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
8
9
  import { err } from "../domain/result.js";
9
10
  /** Register provider-backed contracts that return atomic Evidence v2 observations. */
@@ -17,7 +18,10 @@ export const registerEvidenceTools = (server, analysis, contracts, options) => {
17
18
  total: 1,
18
19
  message: "started",
19
20
  });
20
- const parameters = jsonObjectSchema.parse(contract.inputSchema.parse(input));
21
+ const parsedInput = safeParseToolInput(contract.inputSchema, input, contract.name);
22
+ if (!parsedInput.ok)
23
+ return toCallToolResult(parsedInput, contract);
24
+ const parameters = jsonObjectSchema.parse(parsedInput.value);
21
25
  if (options.permissionAuthority !== undefined) {
22
26
  const request = permissionRequest(contract.name, parameters);
23
27
  if (request !== undefined) {
@@ -4,21 +4,29 @@ import { jsonValueSchema } from "../domain/jsonValue.js";
4
4
  import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
5
5
  import { toCallToolResult } from "./toolResult.js";
6
6
  import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
7
- import { resolveSessionEvidence } from "./sessionEvidence.js";
7
+ import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
8
8
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
9
  import { runDerivedOperation } from "./runDerivedOperation.js";
10
+ import { safeParseToolInput } from "./toolInputValidation.js";
10
11
  /** Register explicit Evidence-backed function comparison. */
11
12
  export const registerFunctionComparisonTool = (server, session, contract) => {
12
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
13
- const parsed = functionComparisonInputSchema.parse(input);
14
- const left = resolveSessionEvidence(session, parsed.left);
14
+ const parsedInput = safeParseToolInput(functionComparisonInputSchema, input, contract.name);
15
+ if (!parsedInput.ok)
16
+ return toCallToolResult(parsedInput, contract);
17
+ const parsed = parsedInput.value;
18
+ const expected = {
19
+ operation: "analyze_function",
20
+ predicate: "rea.analysis/v2",
21
+ };
22
+ const left = resolveSessionEvidenceIds(session, parsed.left_evidence_ids, expected);
15
23
  if (!left.ok)
16
24
  return toCallToolResult(left, contract);
17
- const right = resolveSessionEvidence(session, parsed.right);
25
+ const right = resolveSessionEvidenceIds(session, parsed.right_evidence_ids, expected);
18
26
  if (!right.ok)
19
27
  return toCallToolResult(right, contract);
20
- const leftIds = evidenceIds(left.value);
21
- const rightIds = evidenceIds(right.value);
28
+ const leftIds = left.value.map(({ evidence_id: id }) => id);
29
+ const rightIds = right.value.map(({ evidence_id: id }) => id);
22
30
  const computed = await runDerivedOperation(context, contract.name, () => compareFunctions(left.value, right.value, parsed.offset, parsed.limit));
23
31
  if (!computed.ok)
24
32
  return toCallToolResult(computed, contract);
@@ -69,4 +77,3 @@ const functionUnknownInput = ({ approved, status, leftIds, rightIds, }) => {
69
77
  relationships: [],
70
78
  };
71
79
  };
72
- const evidenceIds = (input) => (Array.isArray(input) ? input : [input]).map(({ evidence_id: id }) => id);
@@ -0,0 +1,74 @@
1
+ import { EvidenceIntegrityError, } from "../../domain/errors.js";
2
+ import { err, ok } from "../../domain/result.js";
3
+ import { recordDerivedEvidence } from "../recordDerivedEvidence.js";
4
+ import { evaluateReconstructionClosure } from "../../domain/reconstructionCoverage.js";
5
+ import { AnalysisInputError } from "../../domain/errors.js";
6
+ /** Build the execution context passed to cross-version investigation. */
7
+ export const investigationContext = ({ session, signal, inputRoots, integrityContinueEnabled, progress, }) => ({
8
+ session,
9
+ signal,
10
+ inputRoots,
11
+ integrityContinueEnabled,
12
+ ...(progress === undefined ? {} : { progress }),
13
+ });
14
+ export const isIncomplete = (status) => status === "unknown" || status === "truncated";
15
+ export const comparisonClosure = (comparisons) => uniqueIds(comparisons.flatMap((evidence) => [
16
+ evidence.evidence_id,
17
+ ...evidence.evidence_links,
18
+ ]));
19
+ export const functionEvidenceIds = (groups) => uniqueIds(groups.flatMap((group) => (Array.isArray(group) ? group : [group]).map(({ evidence_id: id }) => id)));
20
+ const uniqueIds = (ids) => [...new Set(ids)].sort((left, right) => left.localeCompare(right));
21
+ export const evidenceClosure = (session, seedIds) => {
22
+ const records = new Map(session
23
+ .exportEvidenceBundle()
24
+ .records.map((evidence) => [evidence.evidence_id, evidence]));
25
+ const visited = new Set();
26
+ const pending = [...seedIds];
27
+ while (pending.length > 0) {
28
+ const evidenceId = pending.pop();
29
+ if (evidenceId === undefined || visited.has(evidenceId))
30
+ continue;
31
+ const evidence = records.get(evidenceId);
32
+ if (evidence === undefined)
33
+ return err(new EvidenceIntegrityError("Investigation input has a dangling Evidence link"));
34
+ visited.add(evidenceId);
35
+ pending.push(...evidence.evidence_links);
36
+ }
37
+ return ok(uniqueIds([...visited]));
38
+ };
39
+ /** Verify a retained coverage boundary before reconstruction evidence is derived. */
40
+ export const verifyCoverageReadiness = (session, coverage) => {
41
+ if (coverage === undefined)
42
+ return ok(null);
43
+ const workspace = session.reconstructionCoverageWorkspace(coverage.workspace_id, coverage.revision);
44
+ if (workspace === undefined ||
45
+ workspace.revision_sha256 !== coverage.revision_sha256)
46
+ return err(new EvidenceIntegrityError("The requested reconstruction coverage revision is not retained by this session"));
47
+ try {
48
+ const result = evaluateReconstructionClosure(workspace, coverage.boundary_id, Date.now());
49
+ return result.status === "ready"
50
+ ? ok(null)
51
+ : err(new EvidenceIntegrityError(`Reconstruction coverage boundary is ${result.status}; readiness requires ready`));
52
+ }
53
+ catch (cause) {
54
+ return err(new AnalysisInputError("verify_reconstruction", { cause }));
55
+ }
56
+ };
57
+ export const recordWorkflowEvidence = (...[session, evidence, approved, unresolved, input]) => {
58
+ if (approved !== true || !unresolved) {
59
+ return recordDerivedEvidence(session, evidence, undefined);
60
+ }
61
+ return recordDerivedEvidence(session, evidence, {
62
+ approved: true,
63
+ question: input.question,
64
+ severity: "high",
65
+ domain: input.domain,
66
+ supporting_evidence_ids: [evidence.evidence_id],
67
+ contradicting_evidence_ids: [],
68
+ required_authority: input.requiredAuthority,
69
+ required_confidence: input.requiredConfidence,
70
+ required_environment: null,
71
+ recommended_probes: [...input.probes],
72
+ relationships: [],
73
+ });
74
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,18 +1,19 @@
1
- import { runCrossVersionInvestigation } from "../application/CrossVersionInvestigation.js";
1
+ import { runCrossVersionInvestigationValidated } from "../application/CrossVersionInvestigation.js";
2
+ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
3
+ import { safeParseToolInput } from "./toolInputValidation.js";
2
4
  import { buildCallPath, callPathInputSchema } from "../domain/callPath.js";
3
5
  import { correlateStaticAndRuntime, staticRuntimeCorrelationInputSchema, } from "../domain/staticRuntimeCorrelation.js";
4
6
  import { reconstructionVerificationInputSchema, verifyReconstruction, } from "../domain/reconstructionVerification.js";
5
7
  import { changedBehaviorResultSchema, changedBehaviorInputSchema, findChangedBehavior, } from "../domain/changedBehavior.js";
6
8
  import { createEvidence } from "../domain/evidence.js";
7
- import { EvidenceIntegrityError, } from "../domain/errors.js";
9
+ import {} from "../domain/errors.js";
8
10
  import { jsonValueSchema } from "../domain/jsonValue.js";
9
- import { err, ok } from "../domain/result.js";
10
11
  import { CALL_PATH_PROVIDER, CHANGED_BEHAVIOR_PROVIDER, RECONSTRUCTION_PROVIDER, STATIC_RUNTIME_PROVIDER, } from "./sessionToolPolicies.js";
11
12
  import { toCallToolResult } from "./toolResult.js";
12
- import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
13
13
  import { mcpProgressReporter } from "./mcpProgress.js";
14
- import { runDerivedOperation } from "./runDerivedOperation.js";
14
+ import { runDerivedOperation, } from "./runDerivedOperation.js";
15
15
  import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../application/DeferredFileAuthorization.js";
16
+ import { comparisonClosure, evidenceClosure, functionEvidenceIds, investigationContext, isIncomplete, recordWorkflowEvidence, verifyCoverageReadiness, } from "./registerInvestigationTools/helpers.js";
16
17
  /** Register Evidence-composed differential investigation workflows. */
17
18
  export const registerInvestigationTools = (server, session, contracts, policies) => {
18
19
  registerChangedBehavior(server, session, contracts[0], policies);
@@ -20,81 +21,23 @@ export const registerInvestigationTools = (server, session, contracts, policies)
20
21
  registerStaticRuntime(server, session, contracts[2]);
21
22
  registerReconstruction(server, session, contracts[3]);
22
23
  };
23
- const investigationExecution = (session, signal, inputRoots, integrityContinueEnabled, progress) => ({
24
- session,
25
- signal,
26
- inputRoots,
27
- integrityContinueEnabled,
28
- ...(progress === undefined ? {} : { progress }),
29
- });
30
- const isIncomplete = (status) => status === "unknown" || status === "truncated";
31
24
  const registerChangedBehavior = (server, session, contract, policies) => {
32
25
  server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
33
- const parsed = changedBehaviorInputSchema.parse(input);
26
+ const parsedInput = safeParseToolInput(changedBehaviorInputSchema, input, contract.name);
27
+ if (!parsedInput.ok)
28
+ return toCallToolResult(parsedInput, contract);
29
+ const parsed = parsedInput.value;
34
30
  const investigationRun = parsed.investigation_run;
35
- if (investigationRun !== undefined) {
36
- const progress = mcpProgressReporter(context);
37
- let workspaceAuthorization;
38
- let authorizeInputRead;
39
- if (policies.permissionAuthority !== undefined) {
40
- const authority = policies.permissionAuthority;
41
- const authorizedWorkspace = await authorizeFileReadWithDeferredWrite(authority, {
42
- path: investigationRun.workspace_path,
43
- readCapability: "investigation_workspace_read",
44
- writeCapability: "investigation_workspace_write",
45
- operation: contract.name,
46
- });
47
- if (!authorizedWorkspace.ok)
48
- return toCallToolResult(authorizedWorkspace, contract);
49
- workspaceAuthorization = authorizedWorkspace.value;
50
- authorizeInputRead = () => authorizeRootPermission(authority, {
51
- capability: "investigation_input",
52
- roots: [investigationRun.left_path, investigationRun.right_path],
53
- access: "read",
54
- operation: contract.name,
55
- });
56
- }
57
- const investigated = await runCrossVersionInvestigation(investigationRun, policies.evidenceFiles, {
58
- ...investigationExecution(session, context.mcpReq.signal, policies.inputRoots, policies.integrityContinueEnabled?.() ?? false, progress),
59
- ...(workspaceAuthorization === undefined
60
- ? {}
61
- : {
62
- authorizeWorkspaceWrite: workspaceAuthorization.authorizeWrite,
63
- }),
64
- ...(authorizeInputRead === undefined ? {} : { authorizeInputRead }),
31
+ if (investigationRun !== undefined)
32
+ return runAutomaticInvestigation({
33
+ server,
34
+ session,
35
+ contract,
36
+ policies,
37
+ investigationRun,
38
+ unknownRegistryApproved: parsed.unknown_registry_approved,
39
+ context,
65
40
  });
66
- if (!investigated.ok)
67
- return toCallToolResult(investigated, contract);
68
- const workspace = investigated.value.workspace;
69
- if (session.retainInvestigationWorkspace(workspace) === "added")
70
- server.sendResourceListChanged();
71
- const result = changedBehaviorResultSchema.parse(investigated.value.evidence.normalized_result);
72
- const toolResult = toCallToolResult(recordWorkflowEvidence(session, investigated.value.evidence, parsed.unknown_registry_approved, isIncomplete(result.behavior_status), {
73
- question: `Automatic changed behavior run ${result.investigation_run?.run_id ?? "unknown"} remains ${result.behavior_status}`,
74
- domain: "changed-behavior",
75
- requiredAuthority: "controlled-replay",
76
- requiredConfidence: "observed",
77
- probes: [
78
- {
79
- operation: "capture_process_scenario",
80
- rationale: "Capture both versions under the same bounded scenario and environment.",
81
- },
82
- ],
83
- }), contract);
84
- return {
85
- ...toolResult,
86
- content: [
87
- ...toolResult.content,
88
- {
89
- type: "resource_link",
90
- uri: `rea://workspace/${workspace.workspace_id}/revision/${String(workspace.revision)}`,
91
- name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
92
- description: "Immutable CAS-linked investigation workspace revision",
93
- mimeType: "application/json",
94
- },
95
- ],
96
- };
97
- }
98
41
  const closure = evidenceClosure(session, comparisonClosure(parsed.comparisons));
99
42
  if (!closure.ok)
100
43
  return toCallToolResult(closure, contract);
@@ -132,9 +75,80 @@ const registerChangedBehavior = (server, session, contract, policies) => {
132
75
  return toCallToolResult(recorded, contract);
133
76
  });
134
77
  };
78
+ const runAutomaticInvestigation = async (input) => {
79
+ const { policies, investigationRun, contract, session } = input;
80
+ const progress = mcpProgressReporter(input.context);
81
+ let workspaceAuthorization;
82
+ let authorizeInputRead;
83
+ if (policies.permissionAuthority !== undefined) {
84
+ const authority = policies.permissionAuthority;
85
+ const authorizedWorkspace = await authorizeFileReadWithDeferredWrite(authority, {
86
+ path: investigationRun.workspace_path,
87
+ readCapability: "investigation_workspace_read",
88
+ writeCapability: "investigation_workspace_write",
89
+ operation: contract.name,
90
+ });
91
+ if (!authorizedWorkspace.ok)
92
+ return toCallToolResult(authorizedWorkspace, contract);
93
+ workspaceAuthorization = authorizedWorkspace.value;
94
+ authorizeInputRead = () => authorizeRootPermission(authority, {
95
+ capability: "investigation_input",
96
+ roots: [investigationRun.left_path, investigationRun.right_path],
97
+ access: "read",
98
+ operation: contract.name,
99
+ });
100
+ }
101
+ const investigated = await runCrossVersionInvestigationValidated(investigationRun, policies.evidenceFiles, {
102
+ ...investigationContext({
103
+ session,
104
+ signal: input.context.mcpReq.signal,
105
+ inputRoots: policies.inputRoots,
106
+ integrityContinueEnabled: policies.integrityContinueEnabled?.() ?? false,
107
+ progress,
108
+ }),
109
+ ...(workspaceAuthorization === undefined
110
+ ? {}
111
+ : { authorizeWorkspaceWrite: workspaceAuthorization.authorizeWrite }),
112
+ ...(authorizeInputRead === undefined ? {} : { authorizeInputRead }),
113
+ });
114
+ if (!investigated.ok)
115
+ return toCallToolResult(investigated, contract);
116
+ const workspace = investigated.value.workspace;
117
+ if (session.retainInvestigationWorkspace(workspace) === "added")
118
+ input.server.sendResourceListChanged();
119
+ const result = changedBehaviorResultSchema.parse(investigated.value.evidence.normalized_result);
120
+ const toolResult = toCallToolResult(recordWorkflowEvidence(session, investigated.value.evidence, input.unknownRegistryApproved, isIncomplete(result.behavior_status), {
121
+ question: `Automatic changed behavior run ${result.investigation_run?.run_id ?? "unknown"} remains ${result.behavior_status}`,
122
+ domain: "changed-behavior",
123
+ requiredAuthority: "controlled-replay",
124
+ requiredConfidence: "observed",
125
+ probes: [
126
+ {
127
+ operation: "capture_process_scenario",
128
+ rationale: "Capture both versions under the same bounded scenario and environment.",
129
+ },
130
+ ],
131
+ }), contract);
132
+ return {
133
+ ...toolResult,
134
+ content: [
135
+ ...toolResult.content,
136
+ {
137
+ type: "resource_link",
138
+ uri: `rea://workspace/${workspace.workspace_id}/revision/${String(workspace.revision)}`,
139
+ name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
140
+ description: "Immutable CAS-linked investigation workspace revision",
141
+ mimeType: "application/json",
142
+ },
143
+ ],
144
+ };
145
+ };
135
146
  const registerCallPath = (server, session, contract) => {
136
147
  server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
137
- const parsed = callPathInputSchema.parse(input);
148
+ const parsedInput = safeParseToolInput(callPathInputSchema, input, contract.name);
149
+ if (!parsedInput.ok)
150
+ return toCallToolResult(parsedInput, contract);
151
+ const parsed = parsedInput.value;
138
152
  const closure = evidenceClosure(session, functionEvidenceIds(parsed.functions));
139
153
  if (!closure.ok)
140
154
  return toCallToolResult(closure, contract);
@@ -177,7 +191,10 @@ const registerCallPath = (server, session, contract) => {
177
191
  };
178
192
  const registerStaticRuntime = (server, session, contract) => {
179
193
  server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
180
- const parsed = staticRuntimeCorrelationInputSchema.parse(input);
194
+ const parsedInput = safeParseToolInput(staticRuntimeCorrelationInputSchema, input, contract.name);
195
+ if (!parsedInput.ok)
196
+ return toCallToolResult(parsedInput, contract);
197
+ const parsed = parsedInput.value;
181
198
  const closure = evidenceClosure(session, comparisonClosure([
182
199
  ...parsed.static_comparisons,
183
200
  ...parsed.runtime_comparisons,
@@ -219,13 +236,14 @@ const registerStaticRuntime = (server, session, contract) => {
219
236
  };
220
237
  const registerReconstruction = (server, session, contract) => {
221
238
  server.registerTool(contract.name, contractOptions(contract), async (input, context) => {
222
- const parsed = reconstructionVerificationInputSchema.parse(input);
239
+ const parsedInput = safeParseToolInput(reconstructionVerificationInputSchema, input, contract.name);
240
+ if (!parsedInput.ok)
241
+ return toCallToolResult(parsedInput, contract);
242
+ const parsed = parsedInput.value;
243
+ const coverage = verifyCoverageReadiness(session, parsed.coverage);
244
+ if (!coverage.ok)
245
+ return toCallToolResult(coverage, contract);
223
246
  const owned = session.exportEvidenceBundle();
224
- const ownedUnknowns = new Set(owned.unknowns.map(({ revision_digest: digest }) => digest));
225
- const ownedEvidenceIds = new Set(owned.records.map(({ evidence_id: id }) => id));
226
- if (parsed.evidence_bundle.records.some(({ evidence_id: id }) => !ownedEvidenceIds.has(id)) ||
227
- parsed.evidence_bundle.unknowns.some(({ revision_digest: digest }) => !ownedUnknowns.has(digest)))
228
- return toCallToolResult(err(new EvidenceIntegrityError("Reconstruction input unknown history is not present in this session")), contract);
229
247
  const computed = await runDerivedOperation(context, contract.name, () => verifyReconstruction(parsed.specification, owned, parsed.offset, parsed.limit));
230
248
  if (!computed.ok)
231
249
  return toCallToolResult(computed, contract);
@@ -261,51 +279,4 @@ const registerReconstruction = (server, session, contract) => {
261
279
  }), contract);
262
280
  });
263
281
  };
264
- const contractOptions = (contract) => ({
265
- description: contract.description,
266
- inputSchema: contract.inputSchema,
267
- outputSchema: contract.outputSchema,
268
- annotations: contract.annotations,
269
- });
270
- const comparisonClosure = (comparisons) => uniqueIds(comparisons.flatMap((evidence) => [
271
- evidence.evidence_id,
272
- ...evidence.evidence_links,
273
- ]));
274
- const functionEvidenceIds = (groups) => uniqueIds(groups.flatMap((group) => (Array.isArray(group) ? group : [group]).map(({ evidence_id: id }) => id)));
275
- const uniqueIds = (ids) => [...new Set(ids)].sort((left, right) => left.localeCompare(right));
276
- const evidenceClosure = (session, seedIds) => {
277
- const records = new Map(session
278
- .exportEvidenceBundle()
279
- .records.map((evidence) => [evidence.evidence_id, evidence]));
280
- const visited = new Set();
281
- const pending = [...seedIds];
282
- while (pending.length > 0) {
283
- const evidenceId = pending.pop();
284
- if (evidenceId === undefined || visited.has(evidenceId))
285
- continue;
286
- const evidence = records.get(evidenceId);
287
- if (evidence === undefined)
288
- return err(new EvidenceIntegrityError("Investigation input has a dangling Evidence link"));
289
- visited.add(evidenceId);
290
- pending.push(...evidence.evidence_links);
291
- }
292
- return ok(uniqueIds([...visited]));
293
- };
294
- const recordWorkflowEvidence = (...[session, evidence, approved, unresolved, input]) => {
295
- if (approved !== true || !unresolved) {
296
- return recordDerivedEvidence(session, evidence, undefined);
297
- }
298
- return recordDerivedEvidence(session, evidence, {
299
- approved: true,
300
- question: input.question,
301
- severity: "high",
302
- domain: input.domain,
303
- supporting_evidence_ids: [evidence.evidence_id],
304
- contradicting_evidence_ids: [],
305
- required_authority: input.requiredAuthority,
306
- required_confidence: input.requiredConfidence,
307
- required_environment: null,
308
- recommended_probes: [...input.probes],
309
- relationships: [],
310
- });
311
- };
282
+ const contractOptions = toolRegistrationOptions;
@@ -0,0 +1,6 @@
1
+ import { MANAGED_TOOL_CONTRACTS } from "../contracts/managedToolContracts.js";
2
+ import { registerEvidenceTools } from "./registerEvidenceTools.js";
3
+ /** Register execution-free managed PE/CLI inspection. */
4
+ export const registerManagedTools = (server, analysis, options) => {
5
+ registerEvidenceTools(server, analysis, MANAGED_TOOL_CONTRACTS, options);
6
+ };