rea-agents 2.5.0 → 3.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 (253) hide show
  1. package/README.md +20 -12
  2. package/bridge/ghidra/ReaGhidraBridge.java +477 -4
  3. package/bridge/hopper_bridge.py +54 -4
  4. package/dist/application/AnalysisContextQueries.js +142 -0
  5. package/dist/application/AnalysisSnapshotCache.js +4 -2
  6. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  7. package/dist/application/ArtifactInventory/policy.js +17 -0
  8. package/dist/application/ArtifactInventory/reader.js +1 -4
  9. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  10. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  11. package/dist/application/ArtifactInventory/types.js +1 -5
  12. package/dist/application/BinarySession.js +19 -20
  13. package/dist/application/BinarySessionComposition.js +21 -0
  14. package/dist/application/BinarySessionRecords.js +106 -10
  15. package/dist/application/BinarySessionStatus.js +11 -5
  16. package/dist/application/BrowserEvidence.js +3 -5
  17. package/dist/application/CapabilityClientRequirements.js +26 -0
  18. package/dist/application/CapabilityInventory.js +140 -55
  19. package/dist/application/ClientRegistrationStatus.js +4 -1
  20. package/dist/application/CrossVersionInventory.js +7 -6
  21. package/dist/application/DirectAnalysis.js +6 -2
  22. package/dist/application/ElectronActiveEvidence.js +55 -0
  23. package/dist/application/ElectronActiveObservationPort.js +1 -0
  24. package/dist/application/ElectronActiveObservationService.js +81 -0
  25. package/dist/application/EnhancedTools.js +49 -17
  26. package/dist/application/EvidenceBundleCommands.js +5 -1
  27. package/dist/application/EvidenceLedger.js +53 -17
  28. package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
  29. package/dist/application/JavaScriptReplayPermission.js +1 -1
  30. package/dist/application/JavaScriptReplayService.js +23 -15
  31. package/dist/application/LazyAnalysisProvider.js +77 -0
  32. package/dist/application/LoopbackReplay.js +1 -1
  33. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  34. package/dist/application/NativeApiInspection.js +80 -0
  35. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  36. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  37. package/dist/application/ProcessCli.js +2 -1
  38. package/dist/application/ProcessHarness.js +8 -3
  39. package/dist/application/ProcessNormalization.js +2 -1
  40. package/dist/application/ProjectPermissionStore.js +1 -0
  41. package/dist/application/ReferenceSourceImport.js +2 -2
  42. package/dist/application/SessionProviderRouter.js +6 -6
  43. package/dist/application/SetupClientConfiguration.js +10 -3
  44. package/dist/application/WindowsCapabilities.js +5 -4
  45. package/dist/application/runtime.js +26 -9
  46. package/dist/artifacts/ArtifactProvider.js +8 -10
  47. package/dist/artifacts/SafeOutputTree.js +7 -8
  48. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  49. package/dist/browser/CdpElectronInspection.js +3 -1
  50. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  51. package/dist/browser/PlaywrightBrowserScenarioProvider.js +8 -2
  52. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  53. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  54. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  55. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  56. package/dist/browser/SensitiveTextCapture.js +1 -1
  57. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  58. package/dist/browser/V8InspectorProvider.js +3 -3
  59. package/dist/catalogIdentity.js +15 -9
  60. package/dist/cli/artifactCommands.js +5 -3
  61. package/dist/cli/coreAnalysisCommands.js +41 -0
  62. package/dist/cli/managedCommands.js +1 -1
  63. package/dist/cliApplicationCommands.js +2 -2
  64. package/dist/cliBrowserAdvancedCommands.js +11 -5
  65. package/dist/cliBrowserCommands.js +14 -7
  66. package/dist/cliCommandNames.js +2 -0
  67. package/dist/cliElectronCommands.js +46 -4
  68. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  69. package/dist/cliObservationOptions.js +4 -0
  70. package/dist/cliPolicyCommands.js +1 -0
  71. package/dist/config/browserScenario.js +77 -0
  72. package/dist/config/electronAutomation.js +35 -0
  73. package/dist/config/environment.js +6 -0
  74. package/dist/config/javascriptReplay.js +41 -0
  75. package/dist/config/managedRuntime.js +25 -0
  76. package/dist/config/parseConfig.js +56 -200
  77. package/dist/config/parsers.js +10 -1
  78. package/dist/config/passiveObservation.js +157 -0
  79. package/dist/config/processCapture.js +47 -0
  80. package/dist/contracts/applicationToolContracts.js +2 -5
  81. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  82. package/dist/contracts/artifactToolContracts.js +35 -37
  83. package/dist/contracts/browserToolContracts.js +2 -2
  84. package/dist/contracts/electronToolContracts.js +30 -1
  85. package/dist/contracts/enhancedInputs.js +21 -27
  86. package/dist/contracts/functionWorkflowToolContracts.js +29 -0
  87. package/dist/contracts/managedToolContracts.js +4 -9
  88. package/dist/contracts/managedWorkflowExamples.js +12 -9
  89. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  90. package/dist/contracts/nativeToolContracts.js +2 -3
  91. package/dist/contracts/promptContracts.js +14 -15
  92. package/dist/contracts/sessionToolSchemas.js +61 -0
  93. package/dist/contracts/toolContractExamples.js +4 -0
  94. package/dist/contracts/toolContractHelpers.js +23 -0
  95. package/dist/contracts/toolContracts.js +12 -67
  96. package/dist/contracts/toolEffects.js +19 -0
  97. package/dist/contracts/toolOutputSchemaGroups.js +66 -11
  98. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  99. package/dist/contracts/toolSchemaMetadata.js +128 -0
  100. package/dist/doctorRuntime.js +1 -1
  101. package/dist/domain/analysisErrorPresentation.js +8 -2
  102. package/dist/domain/analysisErrorProjection.js +1 -0
  103. package/dist/domain/androidApplication.js +2 -0
  104. package/dist/domain/appleApplication.js +2 -0
  105. package/dist/domain/binaryTarget.js +7 -5
  106. package/dist/domain/binaryTargetTypes.js +1 -0
  107. package/dist/domain/browserCaptureComparison.js +21 -69
  108. package/dist/domain/browserObservation.js +22 -9
  109. package/dist/domain/bytecodeProvider.js +177 -0
  110. package/dist/domain/callPath.js +3 -2
  111. package/dist/domain/conformancePackage.js +169 -0
  112. package/dist/domain/conformanceReplay.js +104 -0
  113. package/dist/domain/conformanceTrustGate.js +328 -0
  114. package/dist/domain/customProtocolCapture.js +137 -0
  115. package/dist/domain/electronActiveObservation.js +277 -0
  116. package/dist/domain/electronObservation.js +15 -11
  117. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  118. package/dist/domain/eventProcessTree.js +217 -0
  119. package/dist/domain/evidenceBundle.js +47 -0
  120. package/dist/domain/functionComparisonNormalization.js +15 -8
  121. package/dist/domain/functionDossierEvidence.js +9 -4
  122. package/dist/domain/hopperStartupFailure.js +1 -1
  123. package/dist/domain/hopperValues.js +68 -68
  124. package/dist/domain/inputIssueProjection.js +11 -2
  125. package/dist/domain/investigationWorkspace.js +16 -15
  126. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  127. package/dist/domain/javascriptReplay.js +79 -63
  128. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  129. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  130. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  131. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  132. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  133. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  134. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  135. package/dist/domain/javascriptSemanticAnalysis.js +8 -12
  136. package/dist/domain/javascriptSourceParser.js +15 -0
  137. package/dist/domain/javascriptStaticAnalysis.js +8 -12
  138. package/dist/domain/knownPageCoverage.js +15 -7
  139. package/dist/domain/mobileApplicationInvestigation.js +159 -0
  140. package/dist/domain/nativeApiBoundary.js +138 -0
  141. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  142. package/dist/domain/objcSwiftMetadata.js +150 -0
  143. package/dist/domain/packageAnalysis.js +123 -0
  144. package/dist/domain/peInspection.js +196 -0
  145. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  146. package/dist/domain/processCaptureValidation.js +7 -3
  147. package/dist/domain/processComparison.js +12 -7
  148. package/dist/domain/processObservation.js +5 -6
  149. package/dist/domain/processReactiveMatching.js +14 -7
  150. package/dist/domain/processReactiveTransition.js +9 -3
  151. package/dist/domain/processScenario.js +6 -3
  152. package/dist/domain/processTraceComparison.js +3 -2
  153. package/dist/domain/protocolCapture.js +245 -0
  154. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  155. package/dist/domain/referenceSourceImportParsing.js +2 -2
  156. package/dist/domain/replayMachineRuntime.js +5 -3
  157. package/dist/domain/sourceToBundleComparison.js +2 -2
  158. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  159. package/dist/domain/sourceToBundleSignals.js +7 -1
  160. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  161. package/dist/domain/webBundleAnalysis.js +14 -14
  162. package/dist/domain/webCaptureDiff.js +15 -12
  163. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  164. package/dist/dotnet/ManagedStaticProvider.js +34 -5
  165. package/dist/generatedMcpToolCatalog.js +37 -0
  166. package/dist/generatedPackageMetadata.js +4 -4
  167. package/dist/ghidra/GhidraClient.js +1 -1
  168. package/dist/ghidra/GhidraClientStartup.js +1 -1
  169. package/dist/ghidra/GhidraDefaults.js +1 -1
  170. package/dist/ghidra/GhidraFunctionValues.js +44 -16
  171. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  172. package/dist/ghidra/GhidraProvider.js +18 -10
  173. package/dist/ghidra/GhidraProviderCapabilities.js +45 -39
  174. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  175. package/dist/ghidra/protocol.js +19 -42
  176. package/dist/hopper/BridgeLauncher.js +3 -1
  177. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  178. package/dist/hopper/HopperCleanup.js +5 -6
  179. package/dist/hopper/HopperClient.js +27 -3
  180. package/dist/hopper/HopperProvider.js +42 -44
  181. package/dist/hopper/HopperRequestQueue.js +32 -4
  182. package/dist/hopper/HopperResponseStream.js +2 -2
  183. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  184. package/dist/hopper/protocol.js +63 -21
  185. package/dist/main/reload.js +1 -6
  186. package/dist/main/state.js +0 -14
  187. package/dist/main/transport.js +31 -41
  188. package/dist/main.js +17 -13
  189. package/dist/mcpDoctor.js +4 -26
  190. package/dist/mcpStartupPolicy.js +14 -0
  191. package/dist/process/PrivateRuntimeRoot.js +17 -0
  192. package/dist/process/ProcessOwnership.js +64 -128
  193. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  194. package/dist/process/ProcessOwnershipObservation.js +88 -0
  195. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  196. package/dist/process/ProviderDeadline.js +8 -12
  197. package/dist/process/WindowsAuthority.js +32 -0
  198. package/dist/reference/ReferenceSourceReader.js +3 -3
  199. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  200. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  201. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  202. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  203. package/dist/replay/ReplayOutcome.js +26 -15
  204. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  205. package/dist/server/createServer.js +101 -144
  206. package/dist/server/mcpClientMetadata.js +32 -0
  207. package/dist/server/registerApplicationTools/characterization.js +6 -13
  208. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  209. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  210. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  211. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  212. package/dist/server/registerApplicationTools/coverage.js +13 -19
  213. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  214. package/dist/server/registerApplicationTools/readiness.js +1 -6
  215. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  216. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  217. package/dist/server/registerArtifactComparisonTool.js +12 -16
  218. package/dist/server/registerBrowserScenarioTool.js +1 -6
  219. package/dist/server/registerBrowserTools.js +37 -79
  220. package/dist/server/registerBundleComparisonTool.js +10 -14
  221. package/dist/server/registerCloseLifecycleTool.js +6 -14
  222. package/dist/server/registerElectronTools.js +30 -47
  223. package/dist/server/registerEnhancedTools.js +124 -122
  224. package/dist/server/registerEvidenceResources.js +50 -101
  225. package/dist/server/registerEvidenceTools.js +5 -9
  226. package/dist/server/registerFunctionComparisonTool.js +11 -15
  227. package/dist/server/registerInvestigationTools.js +42 -59
  228. package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
  229. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  230. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  231. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  232. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  233. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  234. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  235. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  236. package/dist/server/registerOfficialTools.js +8 -9
  237. package/dist/server/registerProcessComparisonTool.js +19 -24
  238. package/dist/server/registerReconstructionObligationLedgerResource.js +0 -7
  239. package/dist/server/registerReconstructionReadinessResource.js +0 -7
  240. package/dist/server/registerReplayMachineTool.js +4 -10
  241. package/dist/server/registerSessionRecordTools.js +146 -47
  242. package/dist/server/registerSessionStatusTool.js +14 -29
  243. package/dist/server/registerSessionTools.js +45 -41
  244. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  245. package/dist/server/sessionToolPolicies.js +1 -5
  246. package/dist/server/toolRegistrationOptions.js +4 -177
  247. package/dist/server/toolResult.js +14 -18
  248. package/package.json +35 -16
  249. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  250. package/scripts/electron-active-hook.cjs +501 -0
  251. package/skills/reverse-engineer-anything/SKILL.md +10 -3
  252. package/dist/server/DynamicToolAvailability.js +0 -70
  253. package/dist/server/toolInputValidation.js +0 -77
@@ -1,137 +1,137 @@
1
1
  import { EnhancedTools, } from "../application/EnhancedTools.js";
2
- import { enhancedInputSchemas, enhancedToolNameSchema, } from "../contracts/enhancedInputs.js";
2
+ import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
3
3
  import { ENHANCED_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
4
- import { toCallToolResult } from "./toolResult.js";
5
- import { logToolExecution } from "./toolLogging.js";
4
+ import { UnknownRegistryError } from "../domain/errors.js";
6
5
  import { createEvidence } from "../domain/evidence.js";
7
- import { AnalysisInputError, UnknownRegistryError } from "../domain/errors.js";
8
- import { ok } from "../domain/result.js";
9
6
  import { mcpProgressReporter } from "./mcpProgress.js";
10
- import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
7
+ import { logToolExecution } from "./toolLogging.js";
11
8
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { safeParseToolInput } from "./toolInputValidation.js";
9
+ import { toCallToolResult } from "./toolResult.js";
13
10
  /** Register composed workflows against the same port as direct bridge tools. */
11
+ // oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
14
12
  export const registerEnhancedTools = (server, analysis, options) => {
15
- for (const contract of ENHANCED_TOOL_CONTRACTS) {
16
- registerEnhancedTool(server, analysis, contract, {
17
- logger: options.logger,
18
- activeTarget: options.activeTarget,
19
- analysisProfile: options.analysisProfile,
20
- recordEvidence: options.recordEvidence,
21
- recordUnknown: options.recordUnknown,
22
- });
23
- }
13
+ const [swiftClasses, objcClasses, objcProtocols, batchDecompile, callGraph, swiftTypes, xrefsToName, binaryOverview, analyzeFunction, inspectNativeApi, traceFeature, codeForString, traceCallPath,] = ENHANCED_TOOL_CONTRACTS;
14
+ server.registerTool(swiftClasses.name, toolRegistrationOptions(swiftClasses), (input, context) => executeEnhancedTool(analysis, options, swiftClasses, {
15
+ validatedCall: { name: "swift_classes", input },
16
+ context,
17
+ }));
18
+ server.registerTool(objcClasses.name, toolRegistrationOptions(objcClasses), (input, context) => executeEnhancedTool(analysis, options, objcClasses, {
19
+ validatedCall: { name: "get_objc_classes", input },
20
+ context,
21
+ }));
22
+ server.registerTool(objcProtocols.name, toolRegistrationOptions(objcProtocols), (input, context) => executeEnhancedTool(analysis, options, objcProtocols, {
23
+ validatedCall: { name: "get_objc_protocols", input },
24
+ context,
25
+ }));
26
+ server.registerTool(batchDecompile.name, toolRegistrationOptions(batchDecompile), (input, context) => executeEnhancedTool(analysis, options, batchDecompile, {
27
+ validatedCall: { name: "batch_decompile", input },
28
+ context,
29
+ }));
30
+ server.registerTool(callGraph.name, toolRegistrationOptions(callGraph), (input, context) => executeEnhancedTool(analysis, options, callGraph, {
31
+ validatedCall: { name: "get_call_graph", input },
32
+ context,
33
+ }));
34
+ server.registerTool(swiftTypes.name, toolRegistrationOptions(swiftTypes), (input, context) => executeEnhancedTool(analysis, options, swiftTypes, {
35
+ validatedCall: { name: "analyze_swift_types", input },
36
+ context,
37
+ }));
38
+ server.registerTool(xrefsToName.name, toolRegistrationOptions(xrefsToName), (input, context) => executeEnhancedTool(analysis, options, xrefsToName, {
39
+ validatedCall: { name: "find_xrefs_to_name", input },
40
+ context,
41
+ }));
42
+ server.registerTool(binaryOverview.name, toolRegistrationOptions(binaryOverview), (input, context) => executeEnhancedTool(analysis, options, binaryOverview, {
43
+ validatedCall: { name: "binary_overview", input },
44
+ context,
45
+ }));
46
+ server.registerTool(analyzeFunction.name, toolRegistrationOptions(analyzeFunction), (input, context) => executeEnhancedTool(analysis, options, analyzeFunction, {
47
+ validatedCall: { name: "analyze_function", input },
48
+ context,
49
+ }));
50
+ server.registerTool(inspectNativeApi.name, toolRegistrationOptions(inspectNativeApi), (input, context) => executeEnhancedTool(analysis, options, inspectNativeApi, {
51
+ validatedCall: { name: "inspect_native_api", input },
52
+ context,
53
+ }));
54
+ server.registerTool(traceFeature.name, toolRegistrationOptions(traceFeature), (input, context) => executeEnhancedTool(analysis, options, traceFeature, {
55
+ validatedCall: { name: "trace_feature", input },
56
+ context,
57
+ }));
58
+ server.registerTool(codeForString.name, toolRegistrationOptions(codeForString), (input, context) => executeEnhancedTool(analysis, options, codeForString, {
59
+ validatedCall: { name: "find_code_for_string", input },
60
+ context,
61
+ }));
62
+ server.registerTool(traceCallPath.name, toolRegistrationOptions(traceCallPath), (input, context) => executeEnhancedTool(analysis, options, traceCallPath, {
63
+ validatedCall: { name: "trace_call_path", input },
64
+ context,
65
+ }));
24
66
  };
25
- const registerEnhancedTool = (server, analysis, contract, registration) => {
26
- const name = enhancedToolNameSchema.parse(contract.name);
27
- server.registerTool(name, toolRegistrationOptions(contract), async (input, context) => {
28
- const progress = mcpProgressReporter(context);
29
- await progress.report({
30
- phase: name,
31
- completed: 0,
32
- total: 1,
33
- message: "started",
67
+ const executeEnhancedTool = async (analysis, registration, contract, request) => {
68
+ const { validatedCall, context } = request;
69
+ const name = validatedCall.name;
70
+ const progress = mcpProgressReporter(context);
71
+ await progress.report({
72
+ phase: name,
73
+ completed: 0,
74
+ total: 1,
75
+ message: "started",
76
+ });
77
+ const parsedInput = validatedCall.input;
78
+ const parameters = jsonParameters(parsedInput);
79
+ const services = new EnhancedTools({
80
+ execute: (operation, operationParameters, executionOptions) => analysis.execute(operation, operationParameters, {
81
+ ...executionOptions,
82
+ progress,
83
+ }),
84
+ });
85
+ const result = await logToolExecution(registration.logger, name, () => services.executeValidated(validatedCall, context.mcpReq.signal));
86
+ await progress.report({
87
+ phase: name,
88
+ completed: 1,
89
+ total: 1,
90
+ message: result.ok ? "completed" : "failed",
91
+ terminal: true,
92
+ });
93
+ if (result.ok) {
94
+ const upstreamProfile = registration.analysisProfile?.();
95
+ const evidence = createEvidence(registration.activeTarget?.(), REA_WORKFLOW_PROVIDER, {
96
+ operation: name,
97
+ parameters,
98
+ result: result.value,
99
+ ...(upstreamProfile === undefined
100
+ ? {}
101
+ : {
102
+ analysisProfile: workflowAnalysisProfile(upstreamProfile),
103
+ }),
104
+ confidence: "derived",
105
+ limitations: [
106
+ "Derived by an REA workflow from one or more provider observations.",
107
+ ],
34
108
  });
35
- const validatedCall = parseEnhancedCall(name, input);
36
- if (!validatedCall.ok)
37
- return toCallToolResult(validatedCall, contract);
38
- const parsedInput = validatedCall.value.input;
39
- const parameters = jsonParameters(parsedInput);
40
- const services = new EnhancedTools({
41
- execute: (operation, operationParameters, executionOptions) => analysis.execute(operation, operationParameters, {
42
- ...executionOptions,
43
- progress,
44
- }),
109
+ const recorded = registration.recordEvidence?.(evidence);
110
+ if (recorded !== undefined && !recorded.ok)
111
+ return toCallToolResult(recorded, contract);
112
+ const unknowns = recordWorkflowUnknowns({
113
+ name,
114
+ input: parameters,
115
+ result: result.value,
116
+ evidenceId: evidence.evidence_id,
117
+ recordUnknown: registration.recordUnknown,
45
118
  });
46
- const result = await logToolExecution(registration.logger, name, () => services.executeValidated(validatedCall.value, context.mcpReq.signal));
47
- await progress.report({
48
- phase: name,
49
- completed: 1,
50
- total: 1,
51
- message: result.ok ? "completed" : "failed",
52
- terminal: true,
119
+ if (!unknowns.ok)
120
+ return toCallToolResult(unknowns, contract);
121
+ return toCallToolResult({ ok: true, value: evidence }, contract, {
122
+ evidenceResourcesAvailable: recorded !== undefined,
53
123
  });
54
- if (result.ok) {
55
- const upstreamProfile = registration.analysisProfile?.();
56
- const evidence = createEvidence(registration.activeTarget?.(), REA_WORKFLOW_PROVIDER, {
57
- operation: name,
58
- parameters,
59
- result: result.value,
60
- ...(upstreamProfile === undefined
61
- ? {}
62
- : {
63
- analysisProfile: workflowAnalysisProfile(upstreamProfile),
64
- }),
65
- confidence: "derived",
66
- limitations: [
67
- "Derived by an REA workflow from one or more provider observations.",
68
- ],
69
- });
70
- const recorded = registration.recordEvidence?.(evidence);
71
- if (recorded !== undefined && !recorded.ok)
72
- return toCallToolResult(recorded, contract);
73
- const unknowns = recordWorkflowUnknowns({
74
- name,
75
- input: parameters,
76
- result: result.value,
77
- evidenceId: evidence.evidence_id,
78
- recordUnknown: registration.recordUnknown,
79
- });
80
- if (!unknowns.ok)
81
- return toCallToolResult(unknowns, contract);
82
- return toCallToolResult({ ok: true, value: evidence }, contract, {
83
- evidenceResourcesAvailable: recorded !== undefined,
84
- });
85
- }
86
- return toCallToolResult(result, contract);
87
- });
88
- };
89
- const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
90
- const ENHANCED_INPUT_PARSERS = {
91
- swift_classes: (input) => safeParseToolInput(enhancedInputSchemas.swift_classes, input, "swift_classes"),
92
- get_objc_classes: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_classes, input, "get_objc_classes"),
93
- get_objc_protocols: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_protocols, input, "get_objc_protocols"),
94
- batch_decompile: (input) => safeParseToolInput(enhancedInputSchemas.batch_decompile, input, "batch_decompile"),
95
- get_call_graph: (input) => safeParseToolInput(enhancedInputSchemas.get_call_graph, input, "get_call_graph"),
96
- analyze_swift_types: (input) => safeParseToolInput(enhancedInputSchemas.analyze_swift_types, input, "analyze_swift_types"),
97
- find_xrefs_to_name: (input) => safeParseToolInput(enhancedInputSchemas.find_xrefs_to_name, input, "find_xrefs_to_name"),
98
- binary_overview: (input) => safeParseToolInput(enhancedInputSchemas.binary_overview, input, "binary_overview"),
99
- analyze_function: (input) => safeParseToolInput(enhancedInputSchemas.analyze_function, input, "analyze_function"),
100
- trace_feature: (input) => safeParseToolInput(enhancedInputSchemas.trace_feature, input, "trace_feature"),
101
- find_code_for_string: (input) => safeParseToolInput(enhancedInputSchemas.find_code_for_string, input, "find_code_for_string"),
102
- trace_call_path: (input) => safeParseToolInput(enhancedInputSchemas.trace_call_path, input, "trace_call_path"),
103
- };
104
- const parseEnhancedCall = (name, input) => {
105
- switch (name) {
106
- case "swift_classes":
107
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.swift_classes(input), (value) => ({ name, input: value }));
108
- case "get_objc_classes":
109
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_classes(input), (value) => ({ name, input: value }));
110
- case "get_objc_protocols":
111
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_protocols(input), (value) => ({ name, input: value }));
112
- case "batch_decompile":
113
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.batch_decompile(input), (value) => ({ name, input: value }));
114
- case "get_call_graph":
115
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_call_graph(input), (value) => ({ name, input: value }));
116
- case "analyze_swift_types":
117
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_swift_types(input), (value) => ({ name, input: value }));
118
- case "find_xrefs_to_name":
119
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.find_xrefs_to_name(input), (value) => ({ name, input: value }));
120
- case "binary_overview":
121
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.binary_overview(input), (value) => ({ name, input: value }));
122
- case "analyze_function":
123
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_function(input), (value) => ({ name, input: value }));
124
- case "trace_feature":
125
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.trace_feature(input), (value) => ({ name, input: value }));
126
- case "find_code_for_string":
127
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.find_code_for_string(input), (value) => ({ name, input: value }));
128
- case "trace_call_path":
129
- return mapEnhancedCall(ENHANCED_INPUT_PARSERS.trace_call_path(input), (value) => ({ name, input: value }));
130
124
  }
125
+ return toCallToolResult(result, contract);
131
126
  };
132
- const mapEnhancedCall = (parsed, project) => parsed.ok ? ok(project(parsed.value)) : parsed;
127
+ const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
133
128
  const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown, }) => {
134
- if (!["trace_feature", "find_code_for_string", "trace_call_path"].includes(name) ||
129
+ if (![
130
+ "trace_feature",
131
+ "find_code_for_string",
132
+ "trace_call_path",
133
+ "inspect_native_api",
134
+ ].includes(name) ||
135
135
  input.unknown_registry_approved !== true ||
136
136
  recordUnknown === undefined ||
137
137
  typeof result !== "object" ||
@@ -146,7 +146,7 @@ const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown
146
146
  approved: true,
147
147
  question,
148
148
  severity: "medium",
149
- domain: "control-flow",
149
+ domain: name === "inspect_native_api" ? "native-api" : "control-flow",
150
150
  supporting_evidence_ids: [evidenceId],
151
151
  contradicting_evidence_ids: [],
152
152
  required_authority: "shipped-artifact",
@@ -155,7 +155,9 @@ const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown
155
155
  recommended_probes: [
156
156
  {
157
157
  operation: name,
158
- rationale: "Continue with a larger bounded budget.",
158
+ rationale: name === "inspect_native_api"
159
+ ? "Confirm the unsupported boundary with a capable provider or ABI probe."
160
+ : "Continue with a larger bounded budget.",
159
161
  },
160
162
  ],
161
163
  relationships: [],
@@ -4,13 +4,12 @@ import canonicalize from "canonicalize";
4
4
  import { registerJavaScriptApplicationGraphResource } from "./registerJavaScriptApplicationGraphResource.js";
5
5
  import { registerReconstructionObligationLedgerResource } from "./registerReconstructionObligationLedgerResource.js";
6
6
  import { registerReconstructionReadinessResource } from "./registerReconstructionReadinessResource.js";
7
- const evidenceUri = (evidenceId) => `rea://evidence/${evidenceId}`;
8
7
  /** Expose immutable session-owned Evidence v2 records as MCP resources. */
9
8
  export const registerEvidenceResources = (server, session) => {
10
9
  registerReconstructionCoverageResource(server, session);
11
10
  registerInvestigationWorkspaceResource(server, session);
12
11
  registerSessionEvidenceResource(server, session);
13
- registerActiveResidualUnknownsResource(server, session);
12
+ registerEvidenceBundleResource(server, session);
14
13
  registerAnalysisSnapshotResource(server, session);
15
14
  registerArtifactPageResource(server, session);
16
15
  registerFunctionDossierResource(server, session);
@@ -19,20 +18,15 @@ export const registerEvidenceResources = (server, session) => {
19
18
  registerReconstructionReadinessResource(server, session);
20
19
  registerJavaScriptApplicationGraphResource(server, session);
21
20
  registerResidualUnknownResource(server, session);
21
+ session.onAnalysisSnapshotChanged?.(() => {
22
+ void server.server
23
+ .sendResourceUpdated({ uri: "rea://snapshot/current" })
24
+ .catch(() => undefined);
25
+ });
22
26
  };
23
27
  const registerReconstructionCoverageResource = (server, session) => {
24
28
  server.registerResource("reconstruction-coverage-revision", new ResourceTemplate("rea://reconstruction-coverage/{workspaceId}/revision/{revision}", {
25
- list: () => ({
26
- resources: session
27
- .reconstructionCoverageWorkspaces()
28
- .map((workspace) => ({
29
- uri: coverageWorkspaceUri(workspace.workspace_id, workspace.revision),
30
- name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
31
- title: `${workspace.name} coverage revision ${String(workspace.revision)}`,
32
- description: "Immutable evidence-backed reconstruction coverage workspace revision.",
33
- mimeType: "application/json",
34
- })),
35
- }),
29
+ list: undefined,
36
30
  }), {
37
31
  title: "Reconstruction coverage revision",
38
32
  description: "Canonical CAS-linked surfaces, owners, claims, verifiers, evidence, and completion boundaries.",
@@ -50,27 +44,7 @@ const registerReconstructionCoverageResource = (server, session) => {
50
44
  };
51
45
  const registerInvestigationWorkspaceResource = (server, session) => {
52
46
  server.registerResource("investigation-workspace-revision", new ResourceTemplate("rea://workspace/{workspaceId}/revision/{revision}", {
53
- list: () => ({
54
- resources: session.investigationWorkspaces().map((workspace) => ({
55
- uri: workspaceUri(workspace.workspace_id, workspace.revision),
56
- name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
57
- title: `${workspace.name} revision ${String(workspace.revision)}`,
58
- description: "Immutable CAS-linked investigation workspace revision.",
59
- mimeType: "application/json",
60
- })),
61
- }),
62
- complete: {
63
- workspaceId: (prefix) => [
64
- ...new Set(session
65
- .investigationWorkspaces()
66
- .map(({ workspace_id }) => workspace_id)),
67
- ].filter((workspaceId) => workspaceId.startsWith(prefix)),
68
- revision: (prefix, context) => session
69
- .investigationWorkspaces()
70
- .filter(({ workspace_id }) => context?.arguments?.workspaceId === workspace_id)
71
- .map(({ revision }) => String(revision))
72
- .filter((revision) => revision.startsWith(prefix)),
73
- },
47
+ list: undefined,
74
48
  }), {
75
49
  title: "Investigation workspace revision",
76
50
  description: "Immutable session-retained workspace with CAS linkage.",
@@ -88,21 +62,7 @@ const registerInvestigationWorkspaceResource = (server, session) => {
88
62
  };
89
63
  const registerSessionEvidenceResource = (server, session) => {
90
64
  server.registerResource("session-evidence", new ResourceTemplate("rea://evidence/{evidenceId}", {
91
- list: () => ({
92
- resources: session.exportEvidenceBundle().records.map((evidence) => ({
93
- uri: evidenceUri(evidence.evidence_id),
94
- name: evidence.evidence_id,
95
- title: `${evidence.operation} evidence`,
96
- description: `Session-owned Evidence v2 record for ${evidence.operation}.`,
97
- mimeType: "application/json",
98
- })),
99
- }),
100
- complete: {
101
- evidenceId: (prefix) => session
102
- .exportEvidenceBundle()
103
- .records.map(({ evidence_id }) => evidence_id)
104
- .filter((evidenceId) => evidenceId.startsWith(prefix)),
105
- },
65
+ list: undefined,
106
66
  }), {
107
67
  title: "Session evidence",
108
68
  description: "Immutable Evidence v2 records owned by this REA session.",
@@ -125,42 +85,52 @@ const registerSessionEvidenceResource = (server, session) => {
125
85
  };
126
86
  });
127
87
  };
128
- const registerActiveResidualUnknownsResource = (server, session) => {
129
- server.registerResource("active-residual-unknowns", "rea://unknowns/active", {
130
- title: "Active residual unknowns",
131
- description: "Current unresolved session-owned residual unknown heads.",
88
+ const registerEvidenceBundleResource = (server, session) => {
89
+ server.registerResource("evidence-bundle", new ResourceTemplate("rea://evidence-bundle/{bundleDigest}", {
90
+ list: undefined,
91
+ }), {
92
+ title: "Evidence bundle",
93
+ description: "Immutable session-retained canonical Evidence v2 bundle.",
132
94
  mimeType: "application/json",
133
- }, (uri) => jsonResource(uri.href, session.listUnknowns().filter(({ status }) => status !== "resolved")));
95
+ }, (uri, variables) => {
96
+ const digest = stringVariable(variables.bundleDigest, uri.href);
97
+ if (!/^[a-f0-9]{64}$/u.test(digest))
98
+ throw new ResourceNotFoundError(uri.href);
99
+ const text = session.retainedEvidenceBundle(digest);
100
+ if (text === undefined)
101
+ throw new ResourceNotFoundError(uri.href);
102
+ return {
103
+ contents: [
104
+ {
105
+ uri: uri.href,
106
+ mimeType: "application/json",
107
+ text,
108
+ },
109
+ ],
110
+ };
111
+ });
134
112
  };
135
113
  const registerAnalysisSnapshotResource = (server, session) => {
136
- server.registerResource("analysis-snapshot", new ResourceTemplate("rea://snapshot/{snapshotDigest}", {
137
- list: () => {
138
- const snapshot = session.exportAnalysisSnapshot();
139
- if (!snapshot.ok)
140
- return { resources: [] };
141
- const digest = contentDigest(snapshot.value);
142
- return {
143
- resources: [
144
- {
145
- uri: `rea://snapshot/${digest}`,
146
- name: digest,
147
- title: "Current analysis snapshot",
148
- description: "Immutable projection of the current target cache.",
149
- mimeType: "application/json",
150
- },
151
- ],
152
- };
153
- },
154
- }), {
114
+ server.registerResource("analysis-snapshot", "rea://snapshot/current", {
155
115
  title: "Analysis snapshot",
156
- description: "Current provider-neutral analysis snapshot by content digest.",
116
+ description: "Mutable provider-neutral analysis snapshot for the current native target.",
157
117
  mimeType: "application/json",
158
- }, (uri, variables) => {
159
- const requested = stringVariable(variables.snapshotDigest, uri.href);
118
+ }, (uri) => {
160
119
  const snapshot = session.exportAnalysisSnapshot();
161
- if (!snapshot.ok || contentDigest(snapshot.value) !== requested)
162
- throw new ResourceNotFoundError(uri.href);
163
- return jsonResource(uri.href, snapshot.value);
120
+ if (!snapshot.ok)
121
+ return jsonResource(uri.href, {
122
+ state: "unavailable",
123
+ reason: snapshot.error.message,
124
+ remediation: "Open a native target with a concrete analysis profile. After metadata mutation, call open_binary again for the current target to begin a fresh cache.",
125
+ });
126
+ return jsonResource(uri.href, {
127
+ state: "available",
128
+ target: snapshot.value.target,
129
+ profile: snapshot.value.binding,
130
+ content_digest: contentDigest(snapshot.value),
131
+ entry_count: snapshot.value.entries.length,
132
+ snapshot: snapshot.value,
133
+ });
164
134
  });
165
135
  };
166
136
  const registerArtifactPageResource = (server, session) => {
@@ -221,7 +191,6 @@ const registerEvidenceSectionResource = (server, session) => {
221
191
  server.registerResource("evidence-section", new ResourceTemplate("rea://evidence/{evidenceId}/section/{section}", {
222
192
  list: undefined,
223
193
  complete: {
224
- evidenceId: (prefix) => evidenceIds(session, prefix),
225
194
  section: (prefix) => EVIDENCE_SECTIONS.filter((section) => section.startsWith(prefix)),
226
195
  },
227
196
  }), {
@@ -251,21 +220,7 @@ const registerEvidenceSectionResource = (server, session) => {
251
220
  };
252
221
  const registerResidualUnknownResource = (server, session) => {
253
222
  server.registerResource("residual-unknown", new ResourceTemplate("rea://unknown/{unknownId}", {
254
- list: () => ({
255
- resources: session.listUnknowns().map((unknown) => ({
256
- uri: `rea://unknown/${unknown.unknown_id}`,
257
- name: unknown.unknown_id,
258
- title: unknown.question,
259
- description: `Current ${unknown.status} residual unknown revision.`,
260
- mimeType: "application/json",
261
- })),
262
- }),
263
- complete: {
264
- unknownId: (prefix) => session
265
- .listUnknowns()
266
- .map(({ unknown_id }) => unknown_id)
267
- .filter((unknownId) => unknownId.startsWith(prefix)),
268
- },
223
+ list: undefined,
269
224
  }), {
270
225
  title: "Residual unknown",
271
226
  description: "Current session-owned residual unknown head.",
@@ -283,8 +238,6 @@ const registerResidualUnknownResource = (server, session) => {
283
238
  return jsonResource(uri.href, { current: unknown, history });
284
239
  });
285
240
  };
286
- const coverageWorkspaceUri = (workspaceId, revision) => `rea://reconstruction-coverage/${workspaceId}/revision/${String(revision)}`;
287
- const workspaceUri = (workspaceId, revision) => `rea://workspace/${workspaceId}/revision/${String(revision)}`;
288
241
  const EVIDENCE_SECTIONS = [
289
242
  "result",
290
243
  "terminal",
@@ -295,10 +248,6 @@ const EVIDENCE_SECTIONS = [
295
248
  "occurrences",
296
249
  "edges",
297
250
  ];
298
- const evidenceIds = (session, prefix) => session
299
- .exportEvidenceBundle()
300
- .records.map(({ evidence_id }) => evidence_id)
301
- .filter((evidenceId) => evidenceId.startsWith(prefix));
302
251
  const stringVariable = (value, uri) => {
303
252
  if (typeof value !== "string")
304
253
  throw new ResourceNotFoundError(uri);
@@ -1,12 +1,11 @@
1
+ import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
1
2
  import { createEvidence } from "../domain/evidence.js";
2
3
  import { jsonObjectSchema } from "../domain/jsonValue.js";
4
+ import { err } from "../domain/result.js";
5
+ import { mcpProgressReporter } from "./mcpProgress.js";
3
6
  import { logToolExecution } from "./toolLogging.js";
4
- import { toCallToolResult } from "./toolResult.js";
5
7
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
6
- import { mcpProgressReporter } from "./mcpProgress.js";
7
- import { safeParseToolInput } from "./toolInputValidation.js";
8
- import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
9
- import { err } from "../domain/result.js";
8
+ import { toCallToolResult } from "./toolResult.js";
10
9
  /** Register provider-backed contracts that return atomic Evidence v2 observations. */
11
10
  export const registerEvidenceTools = (server, analysis, contracts, options) => {
12
11
  for (const contract of contracts) {
@@ -18,10 +17,7 @@ export const registerEvidenceTools = (server, analysis, contracts, options) => {
18
17
  total: 1,
19
18
  message: "started",
20
19
  });
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);
20
+ const parameters = jsonObjectSchema.parse(input);
25
21
  if (options.permissionAuthority !== undefined) {
26
22
  const request = permissionRequest(contract.name, parameters);
27
23
  if (request !== undefined) {
@@ -1,33 +1,29 @@
1
- import { compareFunctions, functionComparisonInputSchema, } from "../domain/functionComparison.js";
1
+ import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
2
2
  import { createEvidence } from "../domain/evidence.js";
3
+ import { compareFunctions } from "../domain/functionComparison.js";
3
4
  import { jsonValueSchema } from "../domain/jsonValue.js";
4
- import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
5
- import { toCallToolResult } from "./toolResult.js";
6
5
  import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
6
+ import { runDerivedOperation } from "./runDerivedOperation.js";
7
7
  import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
8
+ import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
8
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
- import { runDerivedOperation } from "./runDerivedOperation.js";
10
- import { safeParseToolInput } from "./toolInputValidation.js";
10
+ import { toCallToolResult } from "./toolResult.js";
11
11
  /** Register explicit Evidence-backed function comparison. */
12
12
  export const registerFunctionComparisonTool = (server, session, contract) => {
13
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
14
- const parsedInput = safeParseToolInput(functionComparisonInputSchema, input, contract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, contract);
17
- const parsed = parsedInput.value;
18
14
  const expected = {
19
15
  operation: "analyze_function",
20
16
  predicate: "rea.analysis/v2",
21
17
  };
22
- const left = resolveSessionEvidenceIds(session, parsed.left_evidence_ids, expected);
18
+ const left = resolveSessionEvidenceIds(session, input.left_evidence_ids, expected);
23
19
  if (!left.ok)
24
20
  return toCallToolResult(left, contract);
25
- const right = resolveSessionEvidenceIds(session, parsed.right_evidence_ids, expected);
21
+ const right = resolveSessionEvidenceIds(session, input.right_evidence_ids, expected);
26
22
  if (!right.ok)
27
23
  return toCallToolResult(right, contract);
28
24
  const leftIds = left.value.map(({ evidence_id: id }) => id);
29
25
  const rightIds = right.value.map(({ evidence_id: id }) => id);
30
- const computed = await runDerivedOperation(context, contract.name, () => compareFunctions(left.value, right.value, parsed.offset, parsed.limit));
26
+ const computed = await runDerivedOperation(context, contract.name, () => compareFunctions(left.value, right.value, input.offset, input.limit));
31
27
  if (!computed.ok)
32
28
  return toCallToolResult(computed, contract);
33
29
  const comparison = computed.value;
@@ -37,8 +33,8 @@ export const registerFunctionComparisonTool = (server, session, contract) => {
37
33
  parameters: {
38
34
  left_evidence_ids: leftIds,
39
35
  right_evidence_ids: rightIds,
40
- offset: parsed.offset,
41
- limit: parsed.limit,
36
+ offset: input.offset,
37
+ limit: input.limit,
42
38
  },
43
39
  result: jsonValueSchema.parse(comparison),
44
40
  confidence: "derived",
@@ -47,7 +43,7 @@ export const registerFunctionComparisonTool = (server, session, contract) => {
47
43
  evidenceLinks: [...leftIds, ...rightIds],
48
44
  });
49
45
  const recorded = recordDerivedEvidence(session, evidence, functionUnknownInput({
50
- approved: parsed.unknown_registry_approved,
46
+ approved: input.unknown_registry_approved,
51
47
  status: comparison.status,
52
48
  leftIds,
53
49
  rightIds,