rea-agents 1.6.0 → 2.0.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 (238) hide show
  1. package/README.md +157 -66
  2. package/bridge/ghidra/ReaGhidraBridge.java +2075 -0
  3. package/bridge/hopper_bridge.py +13 -3
  4. package/dist/application/AbortablePromise.js +25 -0
  5. package/dist/application/AnalysisProvider.js +3 -0
  6. package/dist/application/AnalysisProviderEvaluation.js +60 -0
  7. package/dist/application/AnalysisProviderRegistry.js +228 -0
  8. package/dist/application/AnalysisSnapshotCache.js +41 -21
  9. package/dist/application/AnalysisSnapshotFiles.js +5 -6
  10. package/dist/application/BinarySession.js +218 -101
  11. package/dist/application/CapabilityInventory.js +18 -0
  12. package/dist/application/CompositeProvider.js +20 -8
  13. package/dist/application/CrossVersionInvestigation.js +10 -6
  14. package/dist/application/DirectAnalysis.js +49 -35
  15. package/dist/application/Doctor.js +110 -8
  16. package/dist/application/ElectronBoundaryAnalysis.js +96 -0
  17. package/dist/application/ElectronBoundaryGraph.js +9 -0
  18. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  19. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  20. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  21. package/dist/application/ElectronBoundaryGraphWindows.js +199 -0
  22. package/dist/application/EnhancedTools.js +39 -14
  23. package/dist/application/InvestigationProviders.js +41 -0
  24. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  25. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  26. package/dist/application/JavaScriptApplicationService.js +74 -0
  27. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  28. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  29. package/dist/application/JavaScriptArtifactAnalysis.js +305 -0
  30. package/dist/application/JavaScriptArtifactAnalysisTypes.js +1 -0
  31. package/dist/application/JavaScriptArtifactFiles.js +231 -0
  32. package/dist/application/JavaScriptArtifactGraphAccumulator.js +54 -0
  33. package/dist/application/JavaScriptArtifactGraphBuilder.js +144 -0
  34. package/dist/application/JavaScriptArtifactGraphContext.js +205 -0
  35. package/dist/application/JavaScriptArtifactGraphDocuments.js +108 -0
  36. package/dist/application/JavaScriptArtifactGraphEvidence.js +99 -0
  37. package/dist/application/JavaScriptArtifactGraphFindings.js +271 -0
  38. package/dist/application/JavaScriptArtifactGraphStructure.js +409 -0
  39. package/dist/application/JavaScriptArtifactReconstruction.js +77 -0
  40. package/dist/application/JavaScriptArtifactReconstructionInput.js +18 -0
  41. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  42. package/dist/application/JavaScriptReplayService.js +266 -0
  43. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  44. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  45. package/dist/application/MacHopper.js +20 -4
  46. package/dist/application/ManagedApplicationGraphService.js +55 -0
  47. package/dist/application/ManagedMemberComparisonService.js +122 -0
  48. package/dist/application/ManagedNativeVerificationService.js +39 -0
  49. package/dist/application/ManagedReconstructionService.js +58 -0
  50. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  51. package/dist/application/PermissionAuthority.js +1 -1
  52. package/dist/application/ProcessCaptureLifecycle.js +1 -1
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProcessSampling.js +16 -12
  55. package/dist/application/ProjectPermissionStore.js +1 -0
  56. package/dist/application/SessionProviderRouter.js +219 -0
  57. package/dist/application/Setup.js +84 -60
  58. package/dist/application/SetupClients.js +1 -1
  59. package/dist/application/SetupPlan.js +9 -2
  60. package/dist/application/SupportedClients.js +40 -16
  61. package/dist/application/Upgrade.js +1 -1
  62. package/dist/application/runtime.js +11 -6
  63. package/dist/artifacts/AsarArtifactReader.js +23 -3
  64. package/dist/browser/CdpBrowserProvider.js +4 -2
  65. package/dist/browser/CdpCaptureEvents.js +49 -0
  66. package/dist/browser/CdpElectronInspection.js +106 -162
  67. package/dist/browser/CdpElectronProvider.js +9 -3
  68. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  69. package/dist/browser/CdpElectronScripts.js +94 -0
  70. package/dist/browser/CdpElectronWorkers.js +56 -0
  71. package/dist/browser/CdpEndpoint.js +14 -1
  72. package/dist/browser/CdpPageCapture.js +8 -4
  73. package/dist/catalogIdentity.js +6 -42
  74. package/dist/cli.js +446 -34
  75. package/dist/cliApplicationCommands.js +62 -0
  76. package/dist/cliBrowserAdvancedCommands.js +5 -4
  77. package/dist/cliBrowserCommands.js +5 -4
  78. package/dist/cliCommandNames.js +56 -0
  79. package/dist/cliElectronCommands.js +106 -3
  80. package/dist/cliEvidenceCommands.js +4 -3
  81. package/dist/cliInvestigationCommands.js +2 -1
  82. package/dist/cliJsonInput.js +54 -0
  83. package/dist/cliPolicyCommands.js +2 -1
  84. package/dist/cliProcessCommands.js +3 -2
  85. package/dist/config.js +101 -2
  86. package/dist/contracts/applicationToolContracts.js +91 -0
  87. package/dist/contracts/artifactToolContracts.js +5 -9
  88. package/dist/contracts/browserToolContracts.js +14 -62
  89. package/dist/contracts/electronToolContracts.js +45 -19
  90. package/dist/contracts/enhancedInputs.js +2 -2
  91. package/dist/contracts/errorSchemas.js +1 -0
  92. package/dist/contracts/investigationExamples.js +0 -6
  93. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  94. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  95. package/dist/contracts/managedToolContracts.js +153 -0
  96. package/dist/contracts/managedWorkflowExamples.js +346 -0
  97. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  98. package/dist/contracts/nativeToolContracts.js +2 -6
  99. package/dist/contracts/promptContracts.js +18 -2
  100. package/dist/contracts/providerSelection.js +28 -0
  101. package/dist/contracts/sessionLifecycleInputs.js +2 -0
  102. package/dist/contracts/toolContractExamples.js +10 -25
  103. package/dist/contracts/toolContracts.js +69 -65
  104. package/dist/contracts/toolEffects.js +160 -0
  105. package/dist/contracts/toolOutputSchemas.js +152 -42
  106. package/dist/doctorRuntime.js +47 -0
  107. package/dist/domain/analysisProfile.js +78 -0
  108. package/dist/domain/analysisSnapshot.js +92 -46
  109. package/dist/domain/artifactComparison.js +3 -4
  110. package/dist/domain/artifactGraph.js +1 -0
  111. package/dist/domain/binaryTarget.js +4 -29
  112. package/dist/domain/browserObservation.js +3 -0
  113. package/dist/domain/bundleComparison.js +4 -4
  114. package/dist/domain/electronObservation.js +13 -0
  115. package/dist/domain/electronStaticAnalysis.js +9 -0
  116. package/dist/domain/electronStaticAnalysisBrowser.js +194 -0
  117. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  118. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  119. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  120. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  121. package/dist/domain/errors.js +148 -7
  122. package/dist/domain/evidence.js +44 -5
  123. package/dist/domain/evidenceBundle.js +9 -7
  124. package/dist/domain/functionComparison.js +9 -3
  125. package/dist/domain/functionComparisonNormalization.js +37 -0
  126. package/dist/domain/functionComparisonSchemas.js +3 -8
  127. package/dist/domain/functionDossierEvidence.js +4 -1
  128. package/dist/domain/hopperValues.js +66 -9
  129. package/dist/domain/inputIssueProjection.js +52 -0
  130. package/dist/domain/investigationWorkspace.js +2 -1
  131. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  132. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  133. package/dist/domain/javascriptApplicationEvidenceSchemas.js +379 -0
  134. package/dist/domain/javascriptApplicationGraph.js +282 -0
  135. package/dist/domain/javascriptApplicationGraphSchemas.js +139 -0
  136. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  137. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  138. package/dist/domain/javascriptApplicationVersionItems.js +221 -0
  139. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  140. package/dist/domain/javascriptAstFingerprint.js +143 -0
  141. package/dist/domain/javascriptFeatureSeed.js +140 -0
  142. package/dist/domain/javascriptFeatureTrace.js +232 -0
  143. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  144. package/dist/domain/javascriptFeatureTraversal.js +88 -0
  145. package/dist/domain/javascriptNativeHandoff.js +85 -0
  146. package/dist/domain/javascriptReplay.js +361 -0
  147. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  148. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  149. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  150. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  151. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  152. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  153. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  154. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  155. package/dist/domain/javascriptRuntimeStaticCandidates.js +191 -0
  156. package/dist/domain/javascriptStaticAnalysis.js +346 -0
  157. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  158. package/dist/domain/javascriptStaticAnalysisHelpers.js +274 -0
  159. package/dist/domain/javascriptStaticAnalysisState.js +23 -0
  160. package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
  161. package/dist/domain/managedApplicationGraph.js +556 -0
  162. package/dist/domain/managedArtifact.js +444 -0
  163. package/dist/domain/managedMemberComparison.js +565 -0
  164. package/dist/domain/managedNativeVerification.js +408 -0
  165. package/dist/domain/managedReconstruction.js +183 -0
  166. package/dist/domain/managedRuntimeCorrelation.js +175 -0
  167. package/dist/domain/reconstructionVerificationSchemas.js +1 -3
  168. package/dist/dotnet/ManagedArtifactInspector.js +318 -0
  169. package/dist/dotnet/ManagedMemberInspector.js +887 -0
  170. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +368 -0
  172. package/dist/dotnet/ManagedMetadataLayout.js +322 -0
  173. package/dist/dotnet/ManagedNativeBoundaryInspector.js +391 -0
  174. package/dist/dotnet/ManagedPeReader.js +157 -0
  175. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  176. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  177. package/dist/generatedPackageMetadata.js +2 -2
  178. package/dist/ghidra/GhidraAnalysisProfile.js +37 -0
  179. package/dist/ghidra/GhidraClient.js +400 -0
  180. package/dist/ghidra/GhidraClientTypes.js +1 -0
  181. package/dist/ghidra/GhidraDefaults.js +20 -0
  182. package/dist/ghidra/GhidraDiagnostics.js +43 -0
  183. package/dist/ghidra/GhidraDoctor.js +59 -0
  184. package/dist/ghidra/GhidraFunctionValues.js +264 -0
  185. package/dist/ghidra/GhidraInstallation.js +239 -0
  186. package/dist/ghidra/GhidraInventoryValues.js +217 -0
  187. package/dist/ghidra/GhidraLauncher.js +139 -0
  188. package/dist/ghidra/GhidraProvider.js +366 -0
  189. package/dist/ghidra/GhidraRequestQueue.js +98 -0
  190. package/dist/ghidra/GhidraResponseBuffer.js +31 -0
  191. package/dist/ghidra/GhidraResponseRouter.js +24 -0
  192. package/dist/ghidra/GhidraSessionError.js +39 -0
  193. package/dist/ghidra/GhidraSessionValues.js +62 -0
  194. package/dist/ghidra/GhidraSocketConnection.js +46 -0
  195. package/dist/ghidra/protocol.js +69 -0
  196. package/dist/hopper/BridgeLauncher.js +19 -54
  197. package/dist/hopper/HopperAnalysisProfile.js +106 -0
  198. package/dist/hopper/HopperClient.js +154 -162
  199. package/dist/hopper/HopperProvider.js +99 -7
  200. package/dist/hopper/HopperSessionValues.js +27 -0
  201. package/dist/hopper/HopperSocketConnection.js +31 -0
  202. package/dist/main.js +14 -0
  203. package/dist/native/NativeMacOSProvider.js +3 -1
  204. package/dist/process/PendingOperations.js +59 -0
  205. package/dist/process/PrivateRuntimeRoot.js +33 -0
  206. package/dist/process/ProviderDeadline.js +95 -0
  207. package/dist/process/ProviderProcess.js +275 -0
  208. package/dist/replay/JavaScriptReplayWorker.js +286 -0
  209. package/dist/replay/LinuxJavaScriptReplayRunner.js +434 -0
  210. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  211. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  212. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  213. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  214. package/dist/server/createServer.js +53 -0
  215. package/dist/server/promptCompletion.js +9 -3
  216. package/dist/server/registerApplicationTools.js +115 -0
  217. package/dist/server/registerArtifactComparisonTool.js +16 -9
  218. package/dist/server/registerBrowserTools.js +33 -8
  219. package/dist/server/registerBundleComparisonTool.js +17 -20
  220. package/dist/server/registerElectronTools.js +45 -3
  221. package/dist/server/registerEnhancedTools.js +67 -19
  222. package/dist/server/registerEvidenceTools.js +5 -1
  223. package/dist/server/registerFunctionComparisonTool.js +14 -7
  224. package/dist/server/registerInvestigationTools.js +21 -17
  225. package/dist/server/registerManagedTools.js +6 -0
  226. package/dist/server/registerManagedWorkflowTools.js +277 -0
  227. package/dist/server/registerOfficialTools.js +11 -8
  228. package/dist/server/registerProcessComparisonTool.js +25 -47
  229. package/dist/server/registerSessionStatusTool.js +7 -7
  230. package/dist/server/registerSessionTools.js +57 -87
  231. package/dist/server/sessionEvidence.js +14 -19
  232. package/dist/server/toolInputValidation.js +77 -0
  233. package/dist/server/toolRegistrationOptions.js +79 -2
  234. package/dist/server/toolResult.js +25 -17
  235. package/package.json +17 -7
  236. package/scripts/rea.mjs +36 -2
  237. package/skills/rea-analysis/SKILL.md +59 -3
  238. /package/dist/{application → process}/ProcessOwnership.js +0 -0
@@ -0,0 +1,160 @@
1
+ const effects = (overrides = {}) => ({
2
+ mutatesTarget: false,
3
+ mutatesSession: false,
4
+ writesFilesystem: false,
5
+ launchesProcess: false,
6
+ accessesNetwork: false,
7
+ changesUiState: false,
8
+ mayDiscardData: false,
9
+ idempotent: true,
10
+ ...overrides,
11
+ });
12
+ const evidence = effects({ mutatesSession: true });
13
+ const nativeEvidence = effects({ mutatesSession: true, launchesProcess: true });
14
+ const browserEvidence = effects({
15
+ mutatesSession: true,
16
+ accessesNetwork: true,
17
+ });
18
+ const sessionEvidence = effects({ mutatesSession: true });
19
+ /** Explicit effect audit for every public tool. */
20
+ export const TOOL_EFFECTS = {
21
+ address_name: evidence,
22
+ comment: evidence,
23
+ current_address: evidence,
24
+ current_procedure: evidence,
25
+ current_document: evidence,
26
+ goto_address: effects({ mutatesSession: true, changesUiState: true }),
27
+ inline_comment: evidence,
28
+ list_bookmarks: evidence,
29
+ list_documents: evidence,
30
+ list_names: evidence,
31
+ list_procedures: evidence,
32
+ list_segments: evidence,
33
+ list_strings: evidence,
34
+ next_address: evidence,
35
+ prev_address: evidence,
36
+ procedure_address: evidence,
37
+ procedure_assembly: evidence,
38
+ procedure_callees: evidence,
39
+ procedure_callers: evidence,
40
+ procedure_info: evidence,
41
+ procedure_references: evidence,
42
+ procedure_pseudo_code: evidence,
43
+ resolve_containing_procedure: evidence,
44
+ search_procedures: evidence,
45
+ search_strings: evidence,
46
+ set_address_name: effects({ mutatesTarget: true, mutatesSession: true }),
47
+ set_addresses_names: effects({ mutatesTarget: true, mutatesSession: true }),
48
+ set_bookmark: effects({ mutatesTarget: true, mutatesSession: true }),
49
+ set_comment: effects({ mutatesTarget: true, mutatesSession: true }),
50
+ set_current_document: effects({ mutatesSession: true, changesUiState: true }),
51
+ set_inline_comment: effects({ mutatesTarget: true, mutatesSession: true }),
52
+ unset_bookmark: effects({
53
+ mutatesTarget: true,
54
+ mutatesSession: true,
55
+ mayDiscardData: true,
56
+ }),
57
+ xrefs: evidence,
58
+ swift_classes: evidence,
59
+ get_objc_classes: evidence,
60
+ get_objc_protocols: evidence,
61
+ batch_decompile: evidence,
62
+ get_call_graph: evidence,
63
+ analyze_swift_types: evidence,
64
+ find_xrefs_to_name: evidence,
65
+ binary_overview: evidence,
66
+ analyze_function: evidence,
67
+ trace_feature: effects({ mutatesSession: true, idempotent: false }),
68
+ inspect_macho: nativeEvidence,
69
+ inspect_signature: nativeEvidence,
70
+ inspect_plist: nativeEvidence,
71
+ list_architectures: nativeEvidence,
72
+ demangle_swift: nativeEvidence,
73
+ inventory_artifact: evidence,
74
+ extract_artifact: effects({ mutatesSession: true, writesFilesystem: true }),
75
+ inspect_managed_artifact: evidence,
76
+ inspect_managed_members: evidence,
77
+ inspect_managed_native_boundaries: evidence,
78
+ compare_managed_members: sessionEvidence,
79
+ verify_managed_native_boundaries: sessionEvidence,
80
+ import_managed_reconstruction: sessionEvidence,
81
+ plan_managed_runtime_correlation: sessionEvidence,
82
+ project_managed_application_graph: sessionEvidence,
83
+ list_browser_targets: browserEvidence,
84
+ inspect_web_page: browserEvidence,
85
+ analyze_web_bundle: browserEvidence,
86
+ observe_web_session: browserEvidence,
87
+ discover_webmcp_tools: browserEvidence,
88
+ compare_web_captures: browserEvidence,
89
+ capture_web_screenshot: browserEvidence,
90
+ compare_web_screenshots: browserEvidence,
91
+ list_electron_targets: browserEvidence,
92
+ inspect_electron_page: browserEvidence,
93
+ analyze_javascript_application: evidence,
94
+ reconcile_javascript_runtime: evidence,
95
+ trace_application_feature: evidence,
96
+ compare_application_versions: evidence,
97
+ run_controlled_replay: effects({
98
+ mutatesSession: true,
99
+ writesFilesystem: true,
100
+ launchesProcess: true,
101
+ }),
102
+ open_binary: effects({ mutatesSession: true, launchesProcess: true }),
103
+ close_binary: effects({
104
+ mutatesSession: true,
105
+ writesFilesystem: true,
106
+ mayDiscardData: true,
107
+ idempotent: false,
108
+ }),
109
+ binary_session: effects(),
110
+ export_evidence_bundle: effects({
111
+ writesFilesystem: true,
112
+ mayDiscardData: true,
113
+ }),
114
+ import_evidence_bundle: effects({ mutatesSession: true }),
115
+ capture_process_scenario: effects({
116
+ mutatesSession: true,
117
+ writesFilesystem: true,
118
+ launchesProcess: true,
119
+ idempotent: false,
120
+ }),
121
+ compare_process_captures: sessionEvidence,
122
+ compare_artifacts: sessionEvidence,
123
+ compare_functions: sessionEvidence,
124
+ compare_bundles: effects({ mutatesSession: true }),
125
+ find_changed_behavior: sessionEvidence,
126
+ build_call_path: sessionEvidence,
127
+ correlate_static_and_runtime: sessionEvidence,
128
+ verify_reconstruction: sessionEvidence,
129
+ list_unknowns: effects(),
130
+ record_unknown: effects({ mutatesSession: true, idempotent: false }),
131
+ update_unknown: effects({ mutatesSession: true, idempotent: false }),
132
+ verify_unknown_resolution: effects(),
133
+ };
134
+ /** Derive MCP annotations without tool-name or tool-family heuristics. */
135
+ export const annotationsFromEffects = (value) => ({
136
+ readOnlyHint: !(value.mutatesTarget ||
137
+ value.mutatesSession ||
138
+ value.writesFilesystem ||
139
+ value.launchesProcess ||
140
+ value.accessesNetwork ||
141
+ value.changesUiState ||
142
+ value.mayDiscardData),
143
+ destructiveHint: value.mayDiscardData,
144
+ idempotentHint: value.idempotent,
145
+ openWorldHint: value.launchesProcess || value.accessesNetwork,
146
+ });
147
+ /** Resolve the audited metadata for one public tool. */
148
+ export const toolContractMetadata = (name) => {
149
+ const audited = TOOL_EFFECTS[name];
150
+ if (audited === undefined)
151
+ throw new Error(`Missing effect audit for ${name}`);
152
+ return {
153
+ title: name
154
+ .split("_")
155
+ .map((word) => word[0]?.toUpperCase() + word.slice(1))
156
+ .join(" "),
157
+ effects: audited,
158
+ annotations: annotationsFromEffects(audited),
159
+ };
160
+ };
@@ -1,11 +1,16 @@
1
1
  import { z } from "zod";
2
- import { evidenceSchema } from "../domain/evidence.js";
3
2
  import { processCaptureComparisonSchema, processCaptureSchema, } from "../domain/processCapture.js";
4
3
  import { evidenceBundleSchema } from "../domain/evidenceBundle.js";
5
4
  import { residualUnknownSchema } from "../domain/residualUnknown.js";
6
- import { functionDossierSchema } from "../domain/hopperValues.js";
5
+ import { functionDossierSchema, localVariableSchema, procedureClassificationSchema, procedureIdentitySchema, referenceKindSchema, } from "../domain/hopperValues.js";
7
6
  import { demangleSwiftSchema, inspectMachoSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/nativeInspection.js";
8
7
  import { artifactExtractionResultSchema, artifactInventoryResultSchema, } from "../domain/artifactGraph.js";
8
+ import { managedArtifactInspectionSchema, managedMemberInspectionSchema, managedNativeBoundaryInspectionSchema, } from "../domain/managedArtifact.js";
9
+ import { managedMemberComparisonResultSchema } from "../domain/managedMemberComparison.js";
10
+ import { managedNativeVerificationResultSchema } from "../domain/managedNativeVerification.js";
11
+ import { managedReconstructionImportResultSchema } from "../domain/managedReconstruction.js";
12
+ import { managedRuntimeCorrelationResultSchema } from "../domain/managedRuntimeCorrelation.js";
13
+ import { managedApplicationGraphResultSchema } from "../domain/managedApplicationGraph.js";
9
14
  import { artifactComparisonResultSchema } from "../domain/artifactComparison.js";
10
15
  import { functionComparisonResultSchema } from "../domain/functionComparison.js";
11
16
  import { bundleComparisonResultSchema } from "../domain/bundleComparison.js";
@@ -14,9 +19,15 @@ import { callPathResultSchema } from "../domain/callPath.js";
14
19
  import { staticRuntimeCorrelationResultSchema } from "../domain/staticRuntimeCorrelation.js";
15
20
  import { reconstructionVerificationResultSchema } from "../domain/reconstructionVerification.js";
16
21
  import { analysisErrorProjectionSchema } from "./errorSchemas.js";
17
- const resultOf = (schema) => evidenceSchema
18
- .omit({ normalized_result: true })
19
- .extend({ normalized_result: schema });
22
+ import { analysisProfileSchema } from "../domain/analysisProfile.js";
23
+ import { PROVIDER_REJECTION_CODES, } from "./providerSelection.js";
24
+ /** Compact MCP result with an immutable link to complete session Evidence. */
25
+ export const evidenceResultOf = (schema) => z.strictObject({
26
+ result: schema,
27
+ evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
28
+ evidence_uri: z.string().regex(/^rea:\/\/evidence\/ev_[a-f0-9]{64}$/u),
29
+ });
30
+ const resultOf = evidenceResultOf;
20
31
  const lifecycleResultOf = (schema) => z.object({ result: schema });
21
32
  /** Resolve a required named output schema or reject contract drift. */
22
33
  export const requireOutputSchema = (schemas, name) => {
@@ -27,6 +38,7 @@ export const requireOutputSchema = (schemas, name) => {
27
38
  };
28
39
  const targetFormatSchema = z.enum([
29
40
  "hopper",
41
+ "analysis-database",
30
42
  "mach-o",
31
43
  "elf",
32
44
  "pe",
@@ -75,10 +87,68 @@ const providerIdentity = z.object({
75
87
  name: z.string(),
76
88
  version: z.string().nullable(),
77
89
  });
90
+ const providerRejectionCode = z.enum(PROVIDER_REJECTION_CODES);
91
+ const providerDiagnostics = z.record(z.string(), z.json());
92
+ const providerAvailability = z.discriminatedUnion("status", [
93
+ z.object({
94
+ status: z.literal("available"),
95
+ code: z.null(),
96
+ reason: z.null(),
97
+ diagnostics: providerDiagnostics,
98
+ }),
99
+ z.object({
100
+ status: z.literal("unavailable"),
101
+ code: providerRejectionCode,
102
+ reason: z.string().min(1),
103
+ diagnostics: providerDiagnostics,
104
+ }),
105
+ ]);
106
+ const providerTargetSupport = z.discriminatedUnion("status", [
107
+ z.object({
108
+ status: z.literal("unknown"),
109
+ code: z.null(),
110
+ reason: z.string().min(1),
111
+ diagnostics: providerDiagnostics,
112
+ }),
113
+ z.object({
114
+ status: z.literal("supported"),
115
+ code: z.null(),
116
+ reason: z.null(),
117
+ diagnostics: providerDiagnostics,
118
+ }),
119
+ z.object({
120
+ status: z.literal("unsupported"),
121
+ code: z.enum([
122
+ "target_kind_unsupported",
123
+ "target_format_unsupported",
124
+ "architecture_unsupported",
125
+ ]),
126
+ reason: z.string().min(1),
127
+ diagnostics: providerDiagnostics,
128
+ }),
129
+ ]);
78
130
  const sessionProvider = z.object({
79
131
  provider: providerIdentity,
80
132
  providers: z.array(providerIdentity),
81
133
  capabilities: z.array(providerCapability),
134
+ analysis_provider_binding: z
135
+ .object({
136
+ provider: providerIdentity,
137
+ selection_source: z.enum([
138
+ "request",
139
+ "environment",
140
+ "auto-single-candidate",
141
+ ]),
142
+ analysis_profile: analysisProfileSchema,
143
+ })
144
+ .nullable(),
145
+ analysis_provider_candidates: z.array(z.object({
146
+ provider: providerIdentity,
147
+ availability: providerAvailability,
148
+ target_support: providerTargetSupport,
149
+ selected: z.boolean(),
150
+ capabilities: z.array(providerCapability),
151
+ })),
82
152
  tool_availability: z.array(z.object({
83
153
  name: z.string(),
84
154
  surface: z.string(),
@@ -93,6 +163,16 @@ const sessionProvider = z.object({
93
163
  "policy_disabled",
94
164
  ]),
95
165
  remediation: z.string().nullable(),
166
+ effects: z.strictObject({
167
+ mutatesTarget: z.boolean(),
168
+ mutatesSession: z.boolean(),
169
+ writesFilesystem: z.boolean(),
170
+ launchesProcess: z.boolean(),
171
+ accessesNetwork: z.boolean(),
172
+ changesUiState: z.boolean(),
173
+ mayDiscardData: z.boolean(),
174
+ idempotent: z.boolean(),
175
+ }),
96
176
  annotations: z.object({
97
177
  read_only: z.boolean(),
98
178
  destructive: z.boolean(),
@@ -144,11 +224,8 @@ const sessionProvider = z.object({
144
224
  const nullableText = z.string().nullable();
145
225
  const addressList = z.array(z.string());
146
226
  const addressedEntry = z.object({ address: z.string(), name: z.string() });
147
- const procedureIdentity = z.object({ address: z.string(), name: z.string() });
148
- const localVariable = z.object({
149
- description: z.string(),
150
- provenance: z.literal("hopper-public-python-api"),
151
- });
227
+ const procedureIdentity = procedureIdentitySchema;
228
+ const localVariable = localVariableSchema;
152
229
  const containingProcedureResolution = z.discriminatedUnion("found", [
153
230
  z.object({
154
231
  query_address: z.string(),
@@ -166,6 +243,10 @@ const unavailable = z.object({
166
243
  available: z.literal(false),
167
244
  reason: z.string(),
168
245
  });
246
+ const availableMemoryPermissions = z.object({
247
+ available: z.literal(true),
248
+ source: z.literal("ghidra-memory-block"),
249
+ });
169
250
  const bounded = (item) => z.object({
170
251
  items: z.array(item),
171
252
  total: z.number().int().min(0).nullable(),
@@ -173,8 +254,36 @@ const bounded = (item) => z.object({
173
254
  truncated: z.boolean(),
174
255
  next_offset: z.number().int().min(0).nullable(),
175
256
  });
257
+ const addressedValue = z.object({
258
+ address: z.string(),
259
+ value: z.string(),
260
+ value_truncated: z.boolean().optional(),
261
+ symbol: z
262
+ .object({
263
+ primary: z.boolean(),
264
+ dynamic: z.boolean(),
265
+ external: z.boolean(),
266
+ type: z.string(),
267
+ source: z.enum(["default", "analysis", "ai", "imported", "user_defined"]),
268
+ })
269
+ .optional(),
270
+ procedure: z
271
+ .object({
272
+ external: z.boolean(),
273
+ thunk: z.boolean(),
274
+ thunk_target: z.string().nullable(),
275
+ })
276
+ .optional(),
277
+ string: z
278
+ .object({
279
+ encoding: z.string(),
280
+ termination: z.enum(["missing", "present_or_not_required"]),
281
+ byte_length: z.number().int().min(0),
282
+ })
283
+ .optional(),
284
+ });
176
285
  const pageOutput = z.object({
177
- items: z.array(z.object({ address: z.string(), value: z.string() })),
286
+ items: z.array(addressedValue),
178
287
  offset: z.number().int().min(0),
179
288
  limit: z.number().int().min(1),
180
289
  total: z.number().int().min(0),
@@ -195,8 +304,12 @@ const memoryRegionOutput = z.object({
195
304
  readable: z.boolean().nullable(),
196
305
  writable: z.boolean().nullable(),
197
306
  executable: z.boolean().nullable(),
198
- permissions: unavailable,
199
- provenance: z.literal("hopper-public-python-api"),
307
+ permissions: z.union([unavailable, availableMemoryPermissions]),
308
+ provenance: z.enum(["hopper-public-python-api", "ghidra-memory-block"]),
309
+ address_space: z.string().optional(),
310
+ image_base: z.string().optional(),
311
+ initialized: z.boolean().optional(),
312
+ overlay: z.boolean().optional(),
200
313
  });
201
314
  const segmentOutput = resultOf(z.array(memoryRegionOutput.extend({ sections: z.array(memoryRegionOutput) })));
202
315
  const procedureInfoOutput = resultOf(z.object({
@@ -206,6 +319,7 @@ const procedureInfoOutput = resultOf(z.object({
206
319
  length: z.number().min(0),
207
320
  signature: nullableText,
208
321
  locals: z.array(localVariable),
322
+ classification: procedureClassificationSchema.nullable().default(null),
209
323
  }));
210
324
  const symbolDiscoveryOutput = (property) => resultOf(z.object({
211
325
  count: z.number().int().min(0),
@@ -224,7 +338,7 @@ const graphNode = z.discriminatedUnion("status", [
224
338
  }),
225
339
  ]);
226
340
  const functionDossierOutput = resultOf(functionDossierSchema);
227
- /** Exact structured-content schemas for the direct Hopper operations. */
341
+ /** Exact structured-content schemas shared by direct analysis providers. */
228
342
  export const officialOutputSchemas = {
229
343
  address_name: resultOf(nullableText),
230
344
  comment: resultOf(nullableText),
@@ -254,7 +368,7 @@ export const officialOutputSchemas = {
254
368
  target_address: z.string(),
255
369
  source_procedure: procedureIdentity.nullable(),
256
370
  target_procedure: procedureIdentity.nullable(),
257
- kind: unavailable,
371
+ kind: referenceKindSchema,
258
372
  })),
259
373
  instructions_scanned: z.number().int().min(0),
260
374
  instruction_scan_truncated: z.boolean(),
@@ -361,6 +475,20 @@ export const artifactOutputSchemas = {
361
475
  inventory_artifact: resultOf(artifactInventoryResultSchema),
362
476
  extract_artifact: resultOf(artifactExtractionResultSchema),
363
477
  };
478
+ /** Exact Evidence v2 schema for execution-free managed static analysis. */
479
+ export const managedOutputSchemas = {
480
+ inspect_managed_artifact: resultOf(managedArtifactInspectionSchema),
481
+ inspect_managed_members: resultOf(managedMemberInspectionSchema),
482
+ inspect_managed_native_boundaries: resultOf(managedNativeBoundaryInspectionSchema),
483
+ };
484
+ /** Exact Evidence v2 schema for provider-neutral managed workflows. */
485
+ export const managedWorkflowOutputSchemas = {
486
+ compare_managed_members: resultOf(managedMemberComparisonResultSchema),
487
+ verify_managed_native_boundaries: resultOf(managedNativeVerificationResultSchema),
488
+ import_managed_reconstruction: resultOf(managedReconstructionImportResultSchema),
489
+ plan_managed_runtime_correlation: resultOf(managedRuntimeCorrelationResultSchema),
490
+ project_managed_application_graph: resultOf(managedApplicationGraphResultSchema),
491
+ };
364
492
  /** Exact structured-content schemas for target lifecycle operations. */
365
493
  export const sessionOutputSchemas = {
366
494
  open_binary: lifecycleResultOf(z.object({
@@ -402,33 +530,15 @@ export const sessionOutputSchemas = {
402
530
  imported: z.number().int().min(0),
403
531
  total: z.number().int().min(0),
404
532
  })),
405
- capture_process_scenario: lifecycleResultOf(evidenceSchema
406
- .omit({ normalized_result: true })
407
- .extend({ normalized_result: processCaptureSchema })),
408
- compare_process_captures: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
409
- normalized_result: processCaptureComparisonSchema,
410
- })),
411
- compare_artifacts: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
412
- normalized_result: artifactComparisonResultSchema,
413
- })),
414
- compare_functions: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
415
- normalized_result: functionComparisonResultSchema,
416
- })),
417
- compare_bundles: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
418
- normalized_result: bundleComparisonResultSchema,
419
- })),
420
- find_changed_behavior: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
421
- normalized_result: changedBehaviorResultSchema,
422
- })),
423
- build_call_path: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
424
- normalized_result: callPathResultSchema,
425
- })),
426
- correlate_static_and_runtime: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
427
- normalized_result: staticRuntimeCorrelationResultSchema,
428
- })),
429
- verify_reconstruction: lifecycleResultOf(evidenceSchema.omit({ normalized_result: true }).extend({
430
- normalized_result: reconstructionVerificationResultSchema,
431
- })),
533
+ capture_process_scenario: resultOf(processCaptureSchema),
534
+ compare_process_captures: resultOf(processCaptureComparisonSchema),
535
+ compare_artifacts: resultOf(artifactComparisonResultSchema),
536
+ compare_functions: resultOf(functionComparisonResultSchema),
537
+ compare_bundles: resultOf(bundleComparisonResultSchema),
538
+ find_changed_behavior: resultOf(changedBehaviorResultSchema),
539
+ build_call_path: resultOf(callPathResultSchema),
540
+ correlate_static_and_runtime: resultOf(staticRuntimeCorrelationResultSchema),
541
+ verify_reconstruction: resultOf(reconstructionVerificationResultSchema),
432
542
  list_unknowns: lifecycleResultOf(z.array(residualUnknownSchema)),
433
543
  record_unknown: lifecycleResultOf(residualUnknownSchema),
434
544
  update_unknown: lifecycleResultOf(residualUnknownSchema),
@@ -0,0 +1,47 @@
1
+ import { systemDoctorHost, } from "./application/Doctor.js";
2
+ import { inspectSystemGhidraProvider } from "./ghidra/GhidraDoctor.js";
3
+ import { parseConfig } from "./config.js";
4
+ import { SystemJavaScriptReplayHost } from "./replay/SystemJavaScriptReplayHost.js";
5
+ /** Compose provider diagnostics at the outer CLI adapter boundary. */
6
+ export const createSystemDoctorHost = () => systemDoctorHost({
7
+ providerInspections: async () => [await inspectSystemGhidraProvider()],
8
+ javascriptReplayCheck: inspectJavaScriptReplay,
9
+ });
10
+ const inspectJavaScriptReplay = async () => {
11
+ const config = parseConfig(process.env);
12
+ if (!config.ok)
13
+ return {
14
+ name: "javascript-replay",
15
+ ok: false,
16
+ classification: "config_drift",
17
+ detail: config.error.message,
18
+ remediation: "Fix the reported REA_JAVASCRIPT_REPLAY_* configuration.",
19
+ };
20
+ if (!config.value.javascriptReplayPolicy.enabled)
21
+ return {
22
+ name: "javascript-replay",
23
+ ok: true,
24
+ classification: "healthy",
25
+ detail: "disabled by default; no extracted-module execution path is admitted",
26
+ };
27
+ try {
28
+ await new SystemJavaScriptReplayHost().probe(config.value.javascriptReplayPolicy);
29
+ return {
30
+ name: "javascript-replay",
31
+ ok: true,
32
+ classification: "healthy",
33
+ detail: "Linux namespace, seccomp, and delegated cgroup probes passed",
34
+ };
35
+ }
36
+ catch (cause) {
37
+ return {
38
+ name: "javascript-replay",
39
+ ok: false,
40
+ classification: process.platform === "linux"
41
+ ? "missing_dependency"
42
+ : "unsupported_host",
43
+ detail: cause instanceof Error ? cause.message : "sandbox probe failed",
44
+ remediation: "Install and configure compatible Bubblewrap and systemd user cgroup delegation, or disable controlled replay.",
45
+ };
46
+ }
47
+ };
@@ -0,0 +1,78 @@
1
+ import { createHash } from "node:crypto";
2
+ import canonicalize from "canonicalize";
3
+ import { z } from "zod";
4
+ import { isJsonWithinLimits } from "./jsonLimits.js";
5
+ import { jsonObjectSchema } from "./jsonValue.js";
6
+ const PROFILE_MAX_BYTES = 64 * 1024;
7
+ const PROFILE_JSON_LIMITS = Object.freeze({
8
+ maxDepth: 16,
9
+ maxStringLength: 16 * 1024,
10
+ maxNodes: 4_096,
11
+ });
12
+ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
13
+ /** Concrete provider identity committed by an analysis profile. */
14
+ export const committedProviderSchema = z.object({
15
+ id: z.string().min(1),
16
+ name: z.string().min(1),
17
+ version: z.string().min(1),
18
+ });
19
+ const boundedParametersSchema = jsonObjectSchema.superRefine((parameters, context) => {
20
+ if (!isJsonWithinLimits(parameters, PROFILE_JSON_LIMITS)) {
21
+ context.addIssue({
22
+ code: "custom",
23
+ message: "Analysis profile parameters exceed structural limits",
24
+ });
25
+ return;
26
+ }
27
+ if (Buffer.byteLength(canonicalJson(parameters), "utf8") > PROFILE_MAX_BYTES)
28
+ context.addIssue({
29
+ code: "custom",
30
+ message: "Analysis profile parameters exceed the byte limit",
31
+ });
32
+ });
33
+ const unsignedAnalysisProfileSchema = z.object({
34
+ schema_version: z.literal(1),
35
+ provider: committedProviderSchema,
36
+ provider_profile_schema_version: z.number().int().min(1),
37
+ parameters: boundedParametersSchema,
38
+ });
39
+ /** Canonical, provider-neutral commitment to analysis-affecting semantics. */
40
+ export const analysisProfileSchema = unsignedAnalysisProfileSchema
41
+ .extend({ digest: digestSchema })
42
+ .superRefine((profile, context) => {
43
+ const { digest: _digest, ...unsigned } = profile;
44
+ if (profileDigest(unsigned) !== profile.digest)
45
+ context.addIssue({
46
+ code: "custom",
47
+ path: ["digest"],
48
+ message: "Analysis profile digest does not match its parameters",
49
+ });
50
+ });
51
+ /** Create a validated RFC 8785 profile commitment at a provider boundary. */
52
+ export const createAnalysisProfile = (provider, providerProfileSchemaVersion, parameters) => {
53
+ const unsigned = unsignedAnalysisProfileSchema.parse({
54
+ schema_version: 1,
55
+ provider,
56
+ provider_profile_schema_version: providerProfileSchemaVersion,
57
+ parameters,
58
+ });
59
+ return analysisProfileSchema.parse({
60
+ ...unsigned,
61
+ digest: profileDigest(unsigned),
62
+ });
63
+ };
64
+ /** Compare two already-validated commitments without interpreting parameters. */
65
+ export const analysisProfilesEqual = (left, right) => left.digest === right.digest &&
66
+ left.provider.id === right.provider.id &&
67
+ left.provider.name === right.provider.name &&
68
+ left.provider.version === right.provider.version &&
69
+ left.schema_version === right.schema_version &&
70
+ left.provider_profile_schema_version ===
71
+ right.provider_profile_schema_version;
72
+ const profileDigest = (profile) => createHash("sha256").update(canonicalJson(profile)).digest("hex");
73
+ const canonicalJson = (value) => {
74
+ const encoded = canonicalize(value);
75
+ if (encoded === undefined)
76
+ throw new TypeError("RFC 8785 canonicalization rejected analysis profile");
77
+ return encoded;
78
+ };