rea-agents 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +23 -17
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +196 -33
  10. package/dist/android/JadxMcpTransport.js +4 -0
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +19 -2
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/CallPathTracing.js +19 -3
  18. package/dist/application/CapabilityInventory.js +6 -3
  19. package/dist/application/ClientConfigurationDocument.js +871 -6
  20. package/dist/application/ClientRegistrationIdentity.js +26 -5
  21. package/dist/application/ClientRegistrationStatus.js +29 -14
  22. package/dist/application/DirectAnalysis.js +27 -37
  23. package/dist/application/Doctor.js +4 -2
  24. package/dist/application/DoctorScope.js +25 -13
  25. package/dist/application/EnhancedLiteralTracing.js +22 -25
  26. package/dist/application/EnhancedTools.js +13 -11
  27. package/dist/application/EvidenceBundleFiles.js +23 -11
  28. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  29. package/dist/application/InventoryProjectionEvidence.js +4 -3
  30. package/dist/application/InvestigationProviders.js +3 -2
  31. package/dist/application/JsonFiles.js +50 -28
  32. package/dist/application/ProcedureAddressResolution.js +11 -0
  33. package/dist/application/ReconstructionCoverageService.js +7 -4
  34. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  35. package/dist/application/Setup.js +13 -1
  36. package/dist/application/SetupClientConfiguration.js +10 -15
  37. package/dist/application/SetupHost.js +5 -2
  38. package/dist/application/SetupPlan.js +5 -3
  39. package/dist/application/SupportedClients.js +34 -1
  40. package/dist/application/Uninstall.js +4 -3
  41. package/dist/application/Update.js +18 -3
  42. package/dist/application/UpdateRuntime.js +46 -25
  43. package/dist/application/WebModuleTraceService.js +4 -2
  44. package/dist/application/WebNetworkCaptureService.js +4 -2
  45. package/dist/application/WebRuntimeService.js +5 -3
  46. package/dist/application/WebScriptExportService.js +2 -2
  47. package/dist/application/WebSourceLocationService.js +4 -2
  48. package/dist/application/WorkflowEvidence.js +82 -0
  49. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  50. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  51. package/dist/application/binary/AnalysisSnapshotCache.js +3 -6
  52. package/dist/application/binary/BinarySession.js +95 -68
  53. package/dist/application/binary/BinarySessionOpen.js +3 -3
  54. package/dist/application/binary/BinarySessionRecords.js +25 -3
  55. package/dist/application/binary/BinarySessionStatus.js +17 -1
  56. package/dist/application/binary/CompositeProvider.js +13 -0
  57. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  58. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  59. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  60. package/dist/application/evm/EvmInterfaceService.js +4 -2
  61. package/dist/application/investigation/EvidenceLedger.js +21 -7
  62. package/dist/application/investigation/InvestigationRecords.js +8 -0
  63. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  64. package/dist/application/javascript/JavaScriptApplicationEvidence.js +24 -3
  65. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  66. package/dist/application/javascript/JavaScriptApplicationService.js +22 -15
  67. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  68. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -4
  69. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  70. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +6 -3
  71. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +11 -3
  72. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  73. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  74. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  75. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  76. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  77. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +23 -1
  78. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  79. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  80. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  81. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  82. package/dist/application/process/ProcessCli.js +14 -6
  83. package/dist/application/process/ProcessEvidence.js +4 -3
  84. package/dist/application/workflowInputError.js +18 -0
  85. package/dist/artifacts/ArtifactProvider.js +12 -2
  86. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  87. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  88. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  89. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  90. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  91. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  92. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  93. package/dist/artifacts/apple/NibArchive.js +81 -14
  94. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  95. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  96. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +13 -8
  97. package/dist/artifacts/inventory/scanCanonical.js +11 -14
  98. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  99. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  100. package/dist/browser/CdpCaptureEventHandlers.js +76 -11
  101. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  102. package/dist/browser/CdpCaptureEvents.js +25 -0
  103. package/dist/browser/CdpConnection.js +30 -11
  104. package/dist/browser/CdpOptionalCommand.js +2 -3
  105. package/dist/browser/CdpPageCapture.js +23 -1
  106. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  107. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  108. package/dist/browser/PlaywrightElectronActiveProvider.js +123 -124
  109. package/dist/browser/WebSourceMapFetcher.js +426 -72
  110. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  111. package/dist/browser/history/CaptureFailures.js +37 -1
  112. package/dist/browser/history/CaptureRelease.js +5 -0
  113. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  114. package/dist/browser/history/HarJson.js +3 -2
  115. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  116. package/dist/cli/analysisSelector.js +23 -0
  117. package/dist/cli/applicationCommands.js +2 -3
  118. package/dist/cli/coreBinaryCommands.js +70 -12
  119. package/dist/cli/electronCommands.js +7 -6
  120. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  121. package/dist/cli/jsonOutput.js +4 -99
  122. package/dist/cli/nativeCallCommands.js +2 -3
  123. package/dist/cli/webRuntimeCommands.js +8 -8
  124. package/dist/cli.js +2 -1
  125. package/dist/cliCommandNames.js +0 -1
  126. package/dist/cliJsonInput.js +9 -4
  127. package/dist/config/environment.js +4 -0
  128. package/dist/config/ghidraStartupTimeout.js +17 -0
  129. package/dist/config/mcpResponseBudget.js +22 -0
  130. package/dist/config/parseConfig.js +2 -1
  131. package/dist/contracts/enhancedInputs.js +5 -3
  132. package/dist/contracts/enhancedToolContracts.js +3 -3
  133. package/dist/contracts/hopperMemoryContracts.js +2 -5
  134. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  135. package/dist/contracts/managed/managedToolContracts.js +2 -4
  136. package/dist/contracts/native/nativeToolContracts.js +4 -2
  137. package/dist/contracts/officialToolContracts.js +14 -15
  138. package/dist/contracts/promptContracts.js +3 -3
  139. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  140. package/dist/contracts/sessionStatusContract.js +2 -4
  141. package/dist/contracts/sessionToolContracts.js +4 -6
  142. package/dist/contracts/sessionToolSchemas.js +2 -5
  143. package/dist/contracts/toolContractExamples.js +0 -1
  144. package/dist/contracts/toolContractHelpers.js +4 -1
  145. package/dist/contracts/toolEffects.js +0 -1
  146. package/dist/contracts/toolOutputSchemaGroups.js +28 -27
  147. package/dist/contracts/toolOutputSchemaPrimitives.js +18 -0
  148. package/dist/contracts/toolSchemaMetadata.js +69 -10
  149. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  150. package/dist/domain/analysisErrorBase.js +8 -3
  151. package/dist/domain/analysisErrorCore.js +3 -1
  152. package/dist/domain/analysisErrorPresentation.js +72 -17
  153. package/dist/domain/analysisErrorProjection.js +106 -27
  154. package/dist/domain/android/androidAnalysis.js +2 -4
  155. package/dist/domain/android/androidApplication.js +17 -9
  156. package/dist/domain/apple/appleApplication.js +41 -14
  157. package/dist/domain/apple/dyldEnvironment.js +73 -0
  158. package/dist/domain/apple/dylibResolution.js +120 -9
  159. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  160. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  161. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  162. package/dist/domain/apple/keyedArchive.js +9 -1
  163. package/dist/domain/apple/machoContainer.js +54 -0
  164. package/dist/domain/apple/plistNumbers.js +76 -0
  165. package/dist/domain/artifactIdentity.js +29 -0
  166. package/dist/domain/artifactInventoryEvidence.js +19 -24
  167. package/dist/domain/bridgeCandidateProjection.js +71 -0
  168. package/dist/domain/browserCompleteness.js +1 -0
  169. package/dist/domain/browserObservationError.js +24 -5
  170. package/dist/domain/browserScenarioValues.js +2 -6
  171. package/dist/domain/bundleComparison.js +3 -2
  172. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  173. package/dist/domain/canonicalOrdering.js +9 -5
  174. package/dist/domain/changedBehavior.js +6 -6
  175. package/dist/domain/comparisonSourceEvidence.js +40 -0
  176. package/dist/domain/configurationErrors.js +1 -1
  177. package/dist/domain/evidence.js +64 -9
  178. package/dist/domain/evidenceBundle.js +42 -1
  179. package/dist/domain/evidenceErrors.js +12 -1
  180. package/dist/domain/explicitSensitiveFailure.js +17 -1
  181. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  182. package/dist/domain/hopperErrors.js +23 -2
  183. package/dist/domain/hopperValues.js +51 -8
  184. package/dist/domain/immutableJson.js +114 -0
  185. package/dist/domain/inputIssueProjection.js +3 -0
  186. package/dist/domain/javascript/electronActiveObservation.js +30 -4
  187. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  188. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  189. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  190. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  191. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  192. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  193. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  194. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  195. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  196. package/dist/domain/javascript/javascriptSemanticGraph.js +13 -0
  197. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  198. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  199. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  200. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  201. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  202. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  203. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  204. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  205. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  206. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  207. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  208. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  209. package/dist/domain/jsonSerialization.js +109 -0
  210. package/dist/domain/jsonValue.js +90 -6
  211. package/dist/domain/localPath.js +6 -0
  212. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  213. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  214. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  215. package/dist/domain/managed/managedNativeVerification.js +3 -9
  216. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  217. package/dist/domain/native/nativeCallObservation.js +33 -11
  218. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  219. package/dist/domain/process/processCapture.js +8 -4
  220. package/dist/domain/process/processComparison.js +38 -4
  221. package/dist/domain/process/processScenario.js +11 -10
  222. package/dist/domain/propertyListKeys.js +1 -1
  223. package/dist/domain/propertyListXmlText.js +19 -0
  224. package/dist/domain/providerAdapterError.js +1 -1
  225. package/dist/domain/providerOperationHealth.js +54 -0
  226. package/dist/domain/reconstructionVerification.js +6 -43
  227. package/dist/domain/reconstructionVerificationSchemas.js +2 -2
  228. package/dist/domain/staticRuntimeCorrelation.js +6 -43
  229. package/dist/domain/webBundleAnalysis.js +20 -8
  230. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  231. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  232. package/dist/domain/webRuntime.js +19 -5
  233. package/dist/domain/webSourceLocation.js +1 -0
  234. package/dist/firmware/FirmwareFiles.js +1 -1
  235. package/dist/generatedPackageMetadata.js +1 -1
  236. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  237. package/dist/ghidra/GhidraClient.js +47 -14
  238. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  239. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  240. package/dist/ghidra/GhidraInstallation.js +18 -21
  241. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  242. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  243. package/dist/ghidra/GhidraLauncher.js +33 -16
  244. package/dist/ghidra/GhidraProviderCapabilities.js +14 -2
  245. package/dist/ghidra/GhidraProviderClient.js +23 -12
  246. package/dist/ghidra/GhidraSessionError.js +11 -7
  247. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  248. package/dist/ghidra/GhidraTransport.js +20 -0
  249. package/dist/hopper/BridgeLauncher.js +31 -11
  250. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  251. package/dist/hopper/HopperCleanup.js +15 -3
  252. package/dist/hopper/HopperClient.js +222 -14
  253. package/dist/hopper/HopperFileOffset.js +237 -0
  254. package/dist/hopper/HopperMachOImage.js +196 -0
  255. package/dist/hopper/HopperOperationStage.js +6 -0
  256. package/dist/hopper/HopperProvider.js +63 -9
  257. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  258. package/dist/hopper/HopperRegexSearch.js +137 -0
  259. package/dist/hopper/HopperRegexWorker.js +27 -0
  260. package/dist/hopper/HopperRequestQueue.js +68 -19
  261. package/dist/hopper/HopperTargetLease.js +3 -2
  262. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  263. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  264. package/dist/inspector/V8InspectorProvider.js +47 -11
  265. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  266. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  267. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  268. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  269. package/dist/mcpDoctor.js +62 -2
  270. package/dist/native/AppleDispatchCoverage.js +47 -6
  271. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  272. package/dist/native/AppleDispatchMetadata.js +6 -3
  273. package/dist/native/AppleMachoFixups.js +48 -24
  274. package/dist/native/AppleMachoSelection.js +32 -16
  275. package/dist/native/AppleObjcCategories.js +6 -2
  276. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  277. package/dist/native/AppleObjcProperties.js +2 -1
  278. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  279. package/dist/native/AppleSwiftVtables.js +21 -15
  280. package/dist/native/CommandRunner.js +81 -84
  281. package/dist/native/LldbCallTracer.js +365 -102
  282. package/dist/native/LldbRetainedObservations.js +178 -0
  283. package/dist/native/NativeCallObservation.js +62 -3
  284. package/dist/native/NativeMacOSProvider.js +98 -17
  285. package/dist/native/SignatureTargetBinding.js +155 -0
  286. package/dist/native/parsers/lipo.js +71 -1
  287. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  288. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  289. package/dist/process/DarwinProcessRunTokenReader.js +8 -9
  290. package/dist/process/ExecFileOutput.js +20 -0
  291. package/dist/process/OwnedCommand.js +7 -2
  292. package/dist/process/ProcessOwnership.js +203 -53
  293. package/dist/process/ProcessOwnershipObservation.js +49 -4
  294. package/dist/process/ProviderProcess.js +38 -7
  295. package/dist/process/capture/ProcessCaptureError.js +2 -2
  296. package/dist/process/capture/ProcessCaptureLifecycle.js +100 -34
  297. package/dist/server/EvidenceMcpServer.js +146 -0
  298. package/dist/server/createServer.js +15 -8
  299. package/dist/server/registerAndroidTools.js +2 -4
  300. package/dist/server/registerApplicationTools/helpers.js +2 -4
  301. package/dist/server/registerArtifactComparisonTool.js +11 -7
  302. package/dist/server/registerBinaryDiagnosticsTools.js +2 -4
  303. package/dist/server/registerBrowserScenarioTool.js +2 -4
  304. package/dist/server/registerBrowserTools.js +2 -4
  305. package/dist/server/registerBundleComparisonTool.js +2 -3
  306. package/dist/server/registerCloseLifecycleTool.js +8 -18
  307. package/dist/server/registerElectronTools.js +2 -4
  308. package/dist/server/registerEnhancedTools.js +18 -59
  309. package/dist/server/registerEvidenceTools.js +2 -4
  310. package/dist/server/registerEvmTools.js +2 -4
  311. package/dist/server/registerFirmwareTools.js +2 -4
  312. package/dist/server/registerFunctionComparisonTool.js +10 -6
  313. package/dist/server/registerInvestigationTools.js +7 -7
  314. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  315. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  316. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  317. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  318. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  319. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  320. package/dist/server/registerOfficialTools.js +2 -4
  321. package/dist/server/registerProcessComparisonTool.js +71 -45
  322. package/dist/server/registerRecordedCrashTools.js +2 -4
  323. package/dist/server/registerSessionRecordTools.js +5 -6
  324. package/dist/server/registerSessionStatusTool.js +17 -3
  325. package/dist/server/registerSessionTools.js +11 -3
  326. package/dist/server/registerWebModuleTool.js +2 -4
  327. package/dist/server/registerWebNetworkCaptureTool.js +2 -4
  328. package/dist/server/registerWebRuntimeTools.js +3 -7
  329. package/dist/server/registerWebScriptTool.js +2 -4
  330. package/dist/server/registerWebSourceLocationTool.js +2 -4
  331. package/dist/server/runDerivedOperation.js +15 -3
  332. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  333. package/dist/server/toolRegistrationOptions.js +2 -2
  334. package/dist/server/toolResult.js +62 -10
  335. package/dist/server/toolResultEncoding.js +33 -0
  336. package/install.sh +1 -1
  337. package/native/windows/build/manifest.json +1 -1
  338. package/package.json +8 -3
  339. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  340. package/scripts/electron-active-hook.cjs +241 -37
  341. package/skills/reverse-engineer-anything/SKILL.md +11 -3
  342. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  343. package/dist/ghidra/GhidraDefaults.js +0 -2
@@ -1,6 +1,26 @@
1
1
  import { basename, isAbsolute, resolve } from "node:path";
2
2
  import { valid } from "semver";
3
3
  import { PRODUCT_IDENTITY } from "../identity.js";
4
+ /** Resolve a pinned npx launcher that stdio clients can spawn on the host. */
5
+ export const npxRegistrationCommand = (platform = process.platform) => {
6
+ const command = [
7
+ "npx",
8
+ "-y",
9
+ PRODUCT_IDENTITY.registrationPackageSpecifier,
10
+ "mcp",
11
+ ];
12
+ return platform === "win32" ? ["cmd.exe", "/d", "/c", ...command] : command;
13
+ };
14
+ const unwrapNpxCommand = (command) => {
15
+ const executable = command[0]?.toLowerCase();
16
+ if (executable !== "cmd" && executable !== "cmd.exe")
17
+ return command;
18
+ if (command[1]?.toLowerCase() === "/c")
19
+ return command.slice(2);
20
+ if (command[1]?.toLowerCase() === "/d" && command[2]?.toLowerCase() === "/c")
21
+ return command.slice(3);
22
+ return [];
23
+ };
4
24
  /** Check that one parsed command points to REA's MCP entry point. */
5
25
  export const isOwnedClientRegistrationCommand = (command, currentCommandPath = resolve(process.argv[1] ?? "unknown")) => {
6
26
  if (command.length === 3 &&
@@ -16,12 +36,13 @@ export const isOwnedClientRegistrationCommand = (command, currentCommandPath = r
16
36
  resolve(executable) === currentCommandPath)
17
37
  return true;
18
38
  }
19
- if (command.length !== 4 ||
20
- command[0] !== "npx" ||
21
- command[1] !== "-y" ||
22
- command[3] !== "mcp")
39
+ const npxCommand = unwrapNpxCommand(command);
40
+ if (npxCommand.length !== 4 ||
41
+ npxCommand[0] !== "npx" ||
42
+ npxCommand[1] !== "-y" ||
43
+ npxCommand[3] !== "mcp")
23
44
  return false;
24
- const packageReference = command[2] ?? "";
45
+ const packageReference = npxCommand[2] ?? "";
25
46
  if (packageReference === PRODUCT_IDENTITY.packageName ||
26
47
  packageReference === PRODUCT_IDENTITY.packageSpecifier ||
27
48
  packageReference === PRODUCT_IDENTITY.registrationPackageSpecifier)
@@ -1,11 +1,11 @@
1
- import { effectiveClientServer, parseClientConfiguration, } from "./ClientConfigurationDocument.js";
1
+ import { effectiveClientServer, grokServerListedDisabled, parseClientConfiguration, } from "./ClientConfigurationDocument.js";
2
2
  import { access, readFile } from "node:fs/promises";
3
3
  import { resolve } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { PRODUCT_IDENTITY } from "../identity.js";
6
6
  import { MCP_STARTUP_POLICY } from "../mcpStartupPolicy.js";
7
- import { isOwnedClientRegistrationCommand } from "./ClientRegistrationIdentity.js";
8
- import { supportedClients } from "./SupportedClients.js";
7
+ import { isOwnedClientRegistrationCommand, npxRegistrationCommand, } from "./ClientRegistrationIdentity.js";
8
+ import { manualRegistrationRemediation, supportedClients, } from "./SupportedClients.js";
9
9
  const registrationSchema = z
10
10
  .object({
11
11
  command: z.string().min(1),
@@ -28,15 +28,30 @@ export const readClientRegistrationStatuses = async (home, currentCommandPath =
28
28
  CLAUDE_CONFIG_DIR: options.environment.CLAUDE_CONFIG_DIR,
29
29
  CODEX_HOME: options.environment.CODEX_HOME,
30
30
  COPILOT_HOME: options.environment.COPILOT_HOME,
31
+ GROK_HOME: options.environment.GROK_HOME,
31
32
  OPENCODE_CONFIG: options.environment.OPENCODE_CONFIG,
33
+ SAND_DATA_ROOT: options.environment.SAND_DATA_ROOT,
32
34
  XDG_CONFIG_HOME: options.environment.XDG_CONFIG_HOME,
33
35
  })) {
34
- if (client.format === "unsupported" ||
35
- (!(await exists(client.markerPath)) && !(await exists(client.configPath))))
36
+ if (!(await exists(client.markerPath)) &&
37
+ !(await exists(client.configPath)))
36
38
  continue;
39
+ const manualRemediation = manualRegistrationRemediation(client.name);
40
+ if (client.format === "unsupported") {
41
+ if (manualRemediation !== undefined)
42
+ statuses.push({
43
+ client: client.name,
44
+ config_path: client.markerPath ?? client.configPath,
45
+ command: [],
46
+ state: "manual",
47
+ remediation: manualRemediation,
48
+ });
49
+ continue;
50
+ }
37
51
  try {
38
52
  const content = await readFile(client.configPath, "utf8");
39
- const raw = effectiveClientServer(parseClientConfiguration(content, client.format), PRODUCT_IDENTITY.mcpServerKey);
53
+ const parsed = parseClientConfiguration(content, client.format);
54
+ const raw = effectiveClientServer(parsed, PRODUCT_IDENTITY.mcpServerKey);
40
55
  if (raw === undefined) {
41
56
  statuses.push(unavailableStatus(client.name, client.configPath, "missing"));
42
57
  continue;
@@ -46,7 +61,9 @@ export const readClientRegistrationStatuses = async (home, currentCommandPath =
46
61
  registration.command,
47
62
  ...registration.args,
48
63
  ];
49
- statuses.push(configuredStatus(client.name, client.configPath, command, registrationAligned(registration, client, currentCommandPath)
64
+ statuses.push(configuredStatus(client.name, client.configPath, command, registrationAligned(registration, client, currentCommandPath, options.platform ?? process.platform) &&
65
+ !(client.format === "grok" &&
66
+ grokServerListedDisabled(parsed.document, PRODUCT_IDENTITY.mcpServerKey))
50
67
  ? "aligned"
51
68
  : "stale"));
52
69
  }
@@ -56,13 +73,13 @@ export const readClientRegistrationStatuses = async (home, currentCommandPath =
56
73
  }
57
74
  return statuses.sort((left, right) => left.client.localeCompare(right.client));
58
75
  };
59
- const registrationAligned = (registration, client, currentCommandPath) => {
76
+ const registrationAligned = (registration, client, currentCommandPath, platform) => {
60
77
  const command = [registration.command, ...registration.args];
61
78
  if (registration.disabled === true || registration.enabled === false)
62
79
  return false;
63
80
  if (!isOwnedClientRegistrationCommand(command, currentCommandPath))
64
81
  return false;
65
- if (client.name === "codex" &&
82
+ if ((client.name === "codex" || client.name === "grok_build") &&
66
83
  registration.startup_timeout_sec !==
67
84
  MCP_STARTUP_POLICY.codexStartupTimeoutSeconds)
68
85
  return false;
@@ -79,11 +96,9 @@ const registrationAligned = (registration, client, currentCommandPath) => {
79
96
  resolve(command[0] ?? "") === resolve(process.execPath) &&
80
97
  resolve(command[1] ?? "") === currentCommandPath)
81
98
  return true;
82
- if (command.length === 4 &&
83
- command[0] === "npx" &&
84
- command[1] === "-y" &&
85
- command[2] === PRODUCT_IDENTITY.registrationPackageSpecifier &&
86
- command[3] === "mcp")
99
+ const npxCommand = npxRegistrationCommand(platform);
100
+ if (command.length === npxCommand.length &&
101
+ command.every((argument, index) => argument === npxCommand[index]))
87
102
  return true;
88
103
  return (command.length === 2 &&
89
104
  command[1] === "mcp" &&
@@ -11,9 +11,9 @@ import { access } from "node:fs/promises";
11
11
  import { readAnalysisSnapshot, writeAnalysisSnapshot, } from "./binary/AnalysisSnapshotFiles.js";
12
12
  import { parseBinaryTarget } from "./BinaryTargetResolver.js";
13
13
  import { snapshotEvidenceForQuery, snapshotMatchesTarget, } from "../domain/analysisSnapshot.js";
14
- import { analysisProfileSchema, committedProviderSchema, } from "../domain/analysisProfile.js";
15
14
  import { err, ok } from "../domain/result.js";
16
15
  import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "./InvestigationProviders.js";
16
+ import { createWorkflowEvidence, workflowSnapshotRecord, recordWorkflowUnknowns, } from "./WorkflowEvidence.js";
17
17
  import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
18
18
  /**
19
19
  * Open one binary, execute one tool, and always release provider resources.
@@ -142,38 +142,32 @@ const runAnalysis = async (dependencies, path, tool, arguments_, options) => {
142
142
  signal,
143
143
  evidenceProfile,
144
144
  });
145
- if (evidence !== undefined)
146
- session.recordEvidence(evidence);
145
+ if (evidence !== undefined) {
146
+ const recorded = session.recordEvidence(evidence);
147
+ if (!recorded.ok)
148
+ return cliError(recorded.error);
149
+ if (isWorkflowEvidenceTool(tool)) {
150
+ const unknowns = recordWorkflowUnknowns({
151
+ name: tool,
152
+ result: evidence.normalized_result,
153
+ evidenceId: evidence.evidence_id,
154
+ recordUnknown: (unknown) => session.recordUnknown(unknown),
155
+ });
156
+ if (!unknowns.ok)
157
+ return cliError(unknowns.error);
158
+ }
159
+ }
147
160
  if (isWorkflowEvidenceTool(tool) &&
148
161
  tool !== "trace_native_ui_action" &&
149
162
  snapshotPath !== undefined &&
150
163
  evidence !== undefined &&
151
- "analysis_profile" in evidence &&
152
164
  session.allowsSnapshotReplay(tool)) {
153
- const recorded = session.recordWorkflowSnapshot({
154
- operation: tool,
155
- parameters: arguments_,
156
- execution: {
157
- result: evidence.normalized_result,
158
- rawResult: evidence.raw_result,
159
- provider: committedProviderSchema.parse(evidence.provider),
160
- analysisProfile: analysisProfileSchema.parse(evidence.analysis_profile),
161
- limitations: evidence.limitations,
162
- locations: evidence.locations,
163
- subject: evidence.subject === null
164
- ? null
165
- : {
166
- path: evidence.subject.local_path,
167
- sha256: evidence.subject.digest.sha256,
168
- format: evidence.subject.format,
169
- ...(evidence.subject.architecture === null
170
- ? {}
171
- : { architecture: evidence.subject.architecture }),
172
- },
173
- },
174
- });
175
- if (!recorded.ok)
176
- return cliError(recorded.error);
165
+ const workflowRecord = workflowSnapshotRecord(evidence, tool);
166
+ if (workflowRecord !== undefined) {
167
+ const recorded = session.recordWorkflowSnapshot(workflowRecord);
168
+ if (!recorded.ok)
169
+ return cliError(recorded.error);
170
+ }
177
171
  }
178
172
  if (tool !== "trace_native_ui_action" &&
179
173
  snapshotPath !== undefined &&
@@ -208,15 +202,12 @@ const executeAnalysisTool = async (input) => {
208
202
  const result = await new EnhancedTools(session).execute(tool, input.arguments, signal);
209
203
  if (!result.ok)
210
204
  return { output: cliError(result.error) };
211
- const evidence = createEvidence(input.openedTarget, REA_WORKFLOW_PROVIDER, {
205
+ const evidence = createWorkflowEvidence({
206
+ target: input.openedTarget,
212
207
  operation: tool,
213
208
  parameters: input.arguments,
214
209
  result: result.value,
215
- ...(evidenceProfile === undefined
216
- ? {}
217
- : { analysisProfile: evidenceProfile }),
218
- confidence: "derived",
219
- limitations: ["Derived by an REA composed workflow."],
210
+ upstreamProfile: evidenceProfile,
220
211
  });
221
212
  return { output: evidence, evidence };
222
213
  }
@@ -280,7 +271,7 @@ const analysisProfileForRoute = (route, tool) => {
280
271
  if (profile === null || profile === undefined)
281
272
  return undefined;
282
273
  if (isWorkflowEvidenceTool(tool))
283
- return workflowAnalysisProfile(profile);
274
+ return workflowAnalysisProfile(profile, tool);
284
275
  const provider = providerIdentityForRoute(route, tool);
285
276
  return provider.id === profile.provider.id ? profile : undefined;
286
277
  };
@@ -294,8 +285,7 @@ const providerIdentityForRoute = (route, operation) => {
294
285
  const analysisProfileForEvidence = (session, tool) => {
295
286
  if (!isWorkflowEvidenceTool(tool))
296
287
  return session.analysisProfile(tool);
297
- const upstream = session.analysisProfile();
298
- return upstream === undefined ? undefined : workflowAnalysisProfile(upstream);
288
+ return session.analysisProfile();
299
289
  };
300
290
  const isWorkflowEvidenceTool = (tool) => tool === "binary_overview" ||
301
291
  tool === "inspect_native_api" ||
@@ -7,6 +7,7 @@ import { parseBinaryTarget } from "./BinaryTargetResolver.js";
7
7
  import { execFileOutput } from "../process/ExecFileOutput.js";
8
8
  import { probeHomebrew } from "./homebrew.js";
9
9
  import { linuxHopperBinarySupported, linuxSharedLibrariesAvailable, readLinuxDistribution, } from "./LinuxHopper.js";
10
+ import { canonicalSkillNeedsInstall } from "./SetupSkill.js";
10
11
  import { CATALOG_IDENTITY } from "../catalogIdentity.js";
11
12
  import { PRODUCT_IDENTITY, SDK_IDENTITY } from "../identity.js";
12
13
  import { readClientRegistrationStatuses, } from "./ClientRegistrationStatus.js";
@@ -61,7 +62,7 @@ const collectDoctorIdentity = async (host) => {
61
62
  checks: [
62
63
  ...(skillAligned ? [] : [skillIdentityCheck(installedSkillIdentity)]),
63
64
  ...registrations
64
- .filter((registration) => registration.state !== "aligned")
65
+ .filter((registration) => registration.state !== "aligned" && registration.state !== "manual")
65
66
  .map(registrationCheck),
66
67
  ],
67
68
  value: {
@@ -96,7 +97,7 @@ const collectDoctorIdentity = async (host) => {
96
97
  };
97
98
  const skillIdentityAligned = (identity) => identity?.version === PRODUCT_IDENTITY.skillVersion &&
98
99
  identity.toolCount === CATALOG_IDENTITY.counts.mcp_tools &&
99
- identity.catalogDigest === CATALOG_IDENTITY.digests.combined_sha256;
100
+ identity.canonical;
100
101
  const skillIdentityCheck = (identity) => ({
101
102
  name: "skill:identity",
102
103
  ok: false,
@@ -281,6 +282,7 @@ const installedSkillIdentity = async (home) => {
281
282
  const content = await readInstalledSkill(home);
282
283
  const countText = /^\s{2}tool_count:\s*(\d+)\s*$/mu.exec(content)?.[1];
283
284
  return {
285
+ canonical: !(await canonicalSkillNeedsInstall(home)),
284
286
  version: /^\s{2}version:\s*"([^"]+)"\s*$/mu.exec(content)?.[1] ?? null,
285
287
  toolCount: countText === undefined ? null : Number.parseInt(countText, 10),
286
288
  catalogDigest: /^\s{2}catalog_digest:\s*"([a-f0-9]{64})"\s*$/mu.exec(content)?.[1] ??
@@ -1,4 +1,5 @@
1
1
  import { uniqueSorted } from "../domain/canonicalOrdering.js";
2
+ import { manualRegistrationRemediation } from "./SupportedClients.js";
2
3
  /** Normalize a caller-selected doctor readiness boundary. */
3
4
  export const normalizeDoctorScope = (requested, target) => ({
4
5
  mode: requested === undefined ? "audit-wide" : "explicit",
@@ -62,22 +63,33 @@ const selectedProviderChecksFor = (providerId, checks, providers) => {
62
63
  },
63
64
  ];
64
65
  };
65
- const selectedRegistrationCheck = (client, status) => status === undefined
66
- ? {
67
- name: `registration:${client}`,
68
- ok: false,
69
- classification: "config_drift",
70
- detail: `Requested client ${client} was not detected.`,
71
- remediation: `Install or select ${client}, then run rea setup --client ${client}.`,
72
- }
73
- : status.state === "aligned"
66
+ const selectedRegistrationCheck = (client, status) => {
67
+ const manual = manualRegistrationRemediation(client);
68
+ if (status === undefined && manual !== undefined)
69
+ return {
70
+ name: `registration:${client}`,
71
+ ok: false,
72
+ classification: "config_drift",
73
+ detail: `${client} is not registered through a local configuration file.`,
74
+ remediation: manual,
75
+ };
76
+ return status === undefined
74
77
  ? {
75
78
  name: `registration:${client}`,
76
- ok: true,
77
- classification: "healthy",
78
- detail: status.config_path,
79
+ ok: false,
80
+ classification: "config_drift",
81
+ detail: `Requested client ${client} was not detected.`,
82
+ remediation: `Install or select ${client}, then run rea setup --client ${client}.`,
79
83
  }
80
- : registrationCheck(status);
84
+ : status.state === "aligned"
85
+ ? {
86
+ name: `registration:${client}`,
87
+ ok: true,
88
+ classification: "healthy",
89
+ detail: status.config_path,
90
+ }
91
+ : registrationCheck(status);
92
+ };
81
93
  const registrationCheck = (status) => ({
82
94
  name: `registration:${status.client}`,
83
95
  ok: false,
@@ -28,32 +28,29 @@ export const traceLiteralFeature = async (call, input, signal) => {
28
28
  };
29
29
  const literalMatches = async (call, input, sources, signal) => {
30
30
  const matches = [];
31
- const needles = [...new Set(input.query.trim().split(/\s+/u))];
32
31
  const matched = new Set();
33
- for (const needle of needles) {
34
- for (const [tool, type] of sources) {
35
- const result = await call(tool, {
36
- pattern: needle,
37
- mode: "literal",
38
- case_sensitive: input.case_sensitive,
39
- }, signal);
40
- if (!result.ok)
41
- return result;
42
- const items = z
43
- .array(z.object({ address: z.string(), value: z.string() }))
44
- .safeParse(result.value);
45
- if (!items.success)
46
- return err(new AnalysisOutputError(tool, "provider returned an invalid search result"));
47
- addPageMatches({
48
- items: items.data.map(({ address, value: name }) => ({
49
- address,
50
- name,
51
- })),
52
- type,
53
- matches,
54
- matched,
55
- });
56
- }
32
+ for (const [tool, type] of sources) {
33
+ const result = await call(tool, {
34
+ pattern: input.query,
35
+ mode: "literal",
36
+ case_sensitive: input.case_sensitive,
37
+ }, signal);
38
+ if (!result.ok)
39
+ return result;
40
+ const items = z
41
+ .array(z.object({ address: z.string(), value: z.string() }))
42
+ .safeParse(result.value);
43
+ if (!items.success)
44
+ return err(new AnalysisOutputError(tool, "provider returned an invalid search result"));
45
+ addPageMatches({
46
+ items: items.data.map(({ address, value: name }) => ({
47
+ address,
48
+ name,
49
+ })),
50
+ type,
51
+ matches,
52
+ matched,
53
+ });
57
54
  }
58
55
  return ok({ matches });
59
56
  };
@@ -3,7 +3,7 @@ import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
3
3
  import { AnalysisCancelledError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
4
4
  import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
5
5
  import {} from "../domain/analysisErrorBase.js";
6
- import { addressDistance, functionDossierSchema, parseDocuments, parseFunctionDossier, parseListCount, parseRelatedAddresses, parseSegments, } from "../domain/hopperValues.js";
6
+ import { addressDistance, functionDossierSchema, parseFunctionDossier, parseListCount, parseRelatedAddresses, parseSegments, } from "../domain/hopperValues.js";
7
7
  import { err, ok } from "../domain/result.js";
8
8
  import { categorizeSwiftTypes, discoverObjcClasses, discoverObjcProtocols, } from "../domain/symbolAnalysis.js";
9
9
  import { inspectNativeDispatch } from "./native/NativeDispatchMetadataInspection.js";
@@ -11,7 +11,9 @@ import { traceNativeValues } from "./native/NativeValueTrace.js";
11
11
  import { traceNativeUiAction } from "./native/NativeUiActionTrace.js";
12
12
  import { jsonValueSchema } from "../domain/jsonValue.js";
13
13
  import { invalidEnhancedInput, } from "./EnhancedToolTypes.js";
14
+ import { resolveAnalysisDocument } from "./AnalysisDocument.js";
14
15
  import { traceCallPath } from "./CallPathTracing.js";
16
+ import { resolveProcedureAddress } from "./ProcedureAddressResolution.js";
15
17
  import { traceLiteralFeature } from "./EnhancedLiteralTracing.js";
16
18
  import { projectNativeApiInspection } from "./native/NativeApiInspection.js";
17
19
  /**
@@ -203,9 +205,12 @@ export class EnhancedTools {
203
205
  async #callGraph(input, signal) {
204
206
  const relation = input.direction === "forward" ? "callees" : "callers";
205
207
  const tool = input.direction === "forward" ? "procedure_callees" : "procedure_callers";
206
- const discovered = new Set([input.address]);
208
+ const resolved = await resolveProcedureAddress(this.#call.bind(this), input.address, signal);
209
+ if (!resolved.ok)
210
+ return resolved;
211
+ const discovered = new Set([resolved.value]);
207
212
  const queue = [
208
- { address: input.address, depth: 0 },
213
+ { address: resolved.value, depth: 0 },
209
214
  ];
210
215
  let queueIndex = 0;
211
216
  const graph = {};
@@ -274,16 +279,16 @@ export class EnhancedTools {
274
279
  });
275
280
  }
276
281
  async #binaryOverview(signal) {
277
- const [segmentsResult, documentsResult, proceduresResult, stringsResult] = await Promise.all([
282
+ const document = await resolveAnalysisDocument(this.analysis, undefined, signal);
283
+ if (!document.ok)
284
+ return document;
285
+ const [segmentsResult, proceduresResult, stringsResult] = await Promise.all([
278
286
  this.#call("list_segments", {}, signal),
279
- this.#call("list_documents", {}, signal),
280
287
  this.#call("list_procedures", {}, signal),
281
288
  this.#call("list_strings", {}, signal),
282
289
  ]);
283
290
  if (!segmentsResult.ok)
284
291
  return segmentsResult;
285
- if (!documentsResult.ok)
286
- return documentsResult;
287
292
  if (!proceduresResult.ok)
288
293
  return proceduresResult;
289
294
  if (!stringsResult.ok)
@@ -291,9 +296,6 @@ export class EnhancedTools {
291
296
  const segments = parseSegments(segmentsResult.value);
292
297
  if (!segments.ok)
293
298
  return segments;
294
- const documents = parseDocuments(documentsResult.value);
295
- if (!documents.ok)
296
- return documents;
297
299
  const procedureCount = parseListCount(proceduresResult.value, "procedures");
298
300
  if (!procedureCount.ok)
299
301
  return procedureCount;
@@ -301,7 +303,7 @@ export class EnhancedTools {
301
303
  if (!stringCount.ok)
302
304
  return stringCount;
303
305
  return ok({
304
- document: documents.value[0] ?? "unknown",
306
+ document: document.value,
305
307
  segments: segments.value.map(({ name, start, end }) => ({
306
308
  name,
307
309
  start,
@@ -1,37 +1,49 @@
1
- import { parseEvidenceBundle, serializeEvidenceBundle, } from "../domain/evidenceBundle.js";
1
+ import { describeEvidenceBundleFailure, describeValidationFailure, parseEvidenceBundle, } from "../domain/evidenceBundle.js";
2
2
  import { EvidenceFileError, EvidenceIntegrityError, } from "../domain/evidenceErrors.js";
3
3
  import { err, ok } from "../domain/result.js";
4
4
  import { parseProcessCapture } from "../domain/process/processCapture.js";
5
- import { readJsonFile, writeTextFile } from "./JsonFiles.js";
5
+ import { bufferedJsonParts, canonicalJsonParts, } from "../domain/jsonSerialization.js";
6
+ import { readJsonFile, writeTextParts } from "./JsonFiles.js";
6
7
  /** Read and validate an evidence bundle at the caller-supplied path. */
7
8
  export const readEvidenceBundle = async (path) => {
8
9
  const loaded = await readJsonFile(path);
9
10
  if (!loaded.ok)
10
11
  return loaded;
12
+ let bundle;
11
13
  try {
12
- const bundle = parseEvidenceBundle(loaded.value);
13
- for (const record of bundle.records) {
14
- if (record.predicate_type === "rea.process-capture")
15
- parseProcessCapture(record.normalized_result);
16
- }
17
- return ok(bundle);
14
+ bundle = parseEvidenceBundle(loaded.value);
18
15
  }
19
16
  catch (cause) {
20
17
  return err(new EvidenceIntegrityError("Evidence bundle validation failed", {
21
18
  cause,
19
+ userMessage: describeEvidenceBundleFailure(loaded.value, cause),
22
20
  }));
23
21
  }
22
+ for (const record of bundle.records) {
23
+ if (record.predicate_type !== "rea.process-capture")
24
+ continue;
25
+ try {
26
+ parseProcessCapture(record.normalized_result);
27
+ }
28
+ catch (cause) {
29
+ return err(new EvidenceIntegrityError("Evidence bundle validation failed", {
30
+ cause,
31
+ userMessage: `Process capture record ${record.evidence_id} has an invalid normalized_result (${describeValidationFailure(cause)}). Recreate or re-export the bundle, then try again.`,
32
+ }));
33
+ }
34
+ }
35
+ return ok(bundle);
24
36
  };
25
37
  /** Atomically write deterministic evidence JSON at the caller-supplied path. */
26
38
  export const writeEvidenceBundle = async (bundle, path, overwrite) => {
27
- let encoded;
39
+ let checked;
28
40
  try {
29
- encoded = serializeEvidenceBundle(bundle);
41
+ checked = parseEvidenceBundle(bundle);
30
42
  }
31
43
  catch (cause) {
32
44
  return err(new EvidenceIntegrityError("Evidence bundle validation failed", {
33
45
  cause,
34
46
  }));
35
47
  }
36
- return writeTextFile(encoded, path, overwrite);
48
+ return writeTextParts(bufferedJsonParts(canonicalJsonParts(checked)), path, overwrite);
37
49
  };
@@ -1,15 +1,14 @@
1
1
  import { toolContract } from "../contracts/toolContracts.js";
2
- import { AnalysisInputError } from "../domain/analysisErrorCore.js";
3
2
  import { createEvidence } from "../domain/evidence.js";
4
3
  import { parseFunctionDossier } from "../domain/hopperValues.js";
5
4
  import { jsonObjectSchema } from "../domain/jsonValue.js";
6
5
  import { err, ok } from "../domain/result.js";
7
- import { projectInputIssues } from "../domain/inputIssueProjection.js";
6
+ import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
8
7
  /** Preserve the provider's observations when presenting a validated function dossier. */
9
8
  export const executeFunctionAnalysisEvidence = async (analysis, parameters, target, options) => {
10
9
  const input = toolContract("analyze_function").inputSchema.safeParse(parameters);
11
10
  if (!input.success)
12
- return err(new AnalysisInputError("analyze_function", { cause: input.error }, projectInputIssues(input.error.issues, parameters)));
11
+ return err(analysisInputErrorFromIssues("analyze_function", input.error.issues, parameters, { cause: input.error }));
13
12
  const arguments_ = jsonObjectSchema.parse(input.data);
14
13
  const execution = await analysis.execute("analyze_function", arguments_, options);
15
14
  if (!execution.ok)
@@ -1,14 +1,15 @@
1
1
  import { z } from "zod";
2
- import { AnalysisInputError, AnalysisProtocolError, } from "../domain/analysisErrorCore.js";
2
+ import { AnalysisProtocolError } from "../domain/analysisErrorCore.js";
3
3
  import {} from "../domain/analysisErrorBase.js";
4
4
  import { createEvidence, } from "../domain/evidence.js";
5
5
  import { jsonValueSchema } from "../domain/jsonValue.js";
6
6
  import { err, ok } from "../domain/result.js";
7
+ import { requestInputError, workflowInputError } from "./workflowInputError.js";
7
8
  /** Parse one inventory projection and wrap its deterministic result in Evidence. */
8
9
  export const projectInventoryEvidence = (options) => {
9
10
  const parsed = options.schema.safeParse(options.rawInput);
10
11
  if (!parsed.success)
11
- return err(new AnalysisInputError(options.operation, { cause: parsed.error }));
12
+ return err(requestInputError(options.operation, parsed.error, options.rawInput));
12
13
  try {
13
14
  const result = options.project(parsed.data);
14
15
  const first = parsed.data.inventory_evidence[0];
@@ -38,7 +39,7 @@ export const projectInventoryEvidence = (options) => {
38
39
  }
39
40
  catch (cause) {
40
41
  return err(cause instanceof TypeError || cause instanceof z.ZodError
41
- ? new AnalysisInputError(options.operation, { cause })
42
+ ? workflowInputError(options.operation, cause)
42
43
  : new AnalysisProtocolError(options.protocolError, { cause }));
43
44
  }
44
45
  };
@@ -5,9 +5,10 @@ export const REA_WORKFLOW_PROVIDER = {
5
5
  name: "REA composed investigation workflow",
6
6
  version: "1",
7
7
  };
8
- /** Commit a workflow result to the exact upstream deep-analysis profile. */
9
- export const workflowAnalysisProfile = (upstream) => createAnalysisProfile(REA_WORKFLOW_PROVIDER, {
8
+ /** Commit a workflow result to its upstream profile and applicable semantic revision. */
9
+ export const workflowAnalysisProfile = (upstream, operation) => createAnalysisProfile(REA_WORKFLOW_PROVIDER, {
10
10
  upstream_analysis_profile: upstream,
11
+ ...(operation === "binary_overview" ? { workflow_revision: 2 } : {}),
11
12
  });
12
13
  /** Provider identity for deterministic artifact inventories. */
13
14
  export const ARTIFACT_GRAPH_PROVIDER = {