rea-agents 6.1.0 → 6.2.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 (453) hide show
  1. package/README.md +7 -5
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +6 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +57 -35
  7. package/dist/application/BinaryTargetResolver.js +5 -3
  8. package/dist/application/BrowserEvidence.js +3 -8
  9. package/dist/application/BrowserScenarioEvidence.js +2 -18
  10. package/dist/application/CapabilityInventory.js +43 -9
  11. package/dist/application/ClientConfigurationDocument.js +69 -25
  12. package/dist/application/DirectAnalysis.js +29 -14
  13. package/dist/application/DirectAnalysisCleanup.js +72 -0
  14. package/dist/application/DirectAnalysisStatus.js +4 -5
  15. package/dist/application/Doctor.js +15 -19
  16. package/dist/application/DoctorDiagnostics.js +1 -2
  17. package/dist/application/EnhancedTools.js +51 -6
  18. package/dist/application/EvidenceBundleFiles.js +8 -3
  19. package/dist/application/InvestigationProviders.js +9 -1
  20. package/dist/application/JsonFiles.js +42 -9
  21. package/dist/application/LinuxHopper.js +9 -6
  22. package/dist/application/MacHopper.js +15 -18
  23. package/dist/application/RealHopperAssertions.js +0 -11
  24. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  25. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  26. package/dist/application/Setup.js +8 -16
  27. package/dist/application/SetupHost.js +16 -27
  28. package/dist/application/SetupPlan.js +6 -6
  29. package/dist/application/Uninstall.js +81 -29
  30. package/dist/application/UpdateMaintenance.js +7 -5
  31. package/dist/application/UpdateRuntime.js +12 -12
  32. package/dist/application/WebScriptExportService.js +30 -4
  33. package/dist/application/WorkflowEvidence.js +25 -2
  34. package/dist/application/XrefsAddressResolution.js +45 -0
  35. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  36. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  37. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  38. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  39. package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
  40. package/dist/application/binary/BinarySession.js +70 -29
  41. package/dist/application/binary/BinarySessionComposition.js +1 -3
  42. package/dist/application/binary/BinarySessionExecution.js +3 -5
  43. package/dist/application/binary/BinarySessionOpen.js +1 -1
  44. package/dist/application/binary/BinarySessionRecords.js +1 -1
  45. package/dist/application/binary/BinarySessionStatus.js +1 -6
  46. package/dist/application/binary/CompositeProvider.js +4 -18
  47. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  48. package/dist/application/binary/SessionProviderRouter.js +27 -135
  49. package/dist/application/homebrew.js +48 -0
  50. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  51. package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
  52. package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
  53. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
  54. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
  55. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  56. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  57. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  58. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  59. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  60. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +43 -16
  61. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
  62. package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
  63. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  64. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  65. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  66. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  67. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  68. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  69. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  70. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +42 -19
  71. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  72. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  73. package/dist/application/process/ProcessCli.js +11 -11
  74. package/dist/application/process/ProcessEvidence.js +0 -1
  75. package/dist/artifacts/ArtifactProvider.js +39 -14
  76. package/dist/artifacts/ArtifactReader.js +31 -0
  77. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  78. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  79. package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
  80. package/dist/artifacts/SafeOutputTree.js +16 -2
  81. package/dist/artifacts/ZipArtifactReader.js +11 -4
  82. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  83. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  84. package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
  85. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  86. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
  87. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  88. package/dist/artifacts/inventory/reader.js +3 -3
  89. package/dist/artifacts/inventory/scanCanonical.js +48 -24
  90. package/dist/artifacts/inventory/scanReader.js +5 -9
  91. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  92. package/dist/browser/CdpBrowserProvider.js +2 -3
  93. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  94. package/dist/browser/CdpCaptureEvents.js +0 -1
  95. package/dist/browser/CdpCaptureValues.js +20 -0
  96. package/dist/browser/CdpElectronProvider.js +0 -2
  97. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  98. package/dist/browser/CdpElectronScripts.js +2 -3
  99. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  100. package/dist/browser/CdpSafeMetadata.js +10 -10
  101. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  102. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  103. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  104. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  105. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  106. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  107. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  108. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  109. package/dist/browser/history/CaptureFailures.js +6 -2
  110. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  111. package/dist/catalogIdentity.js +0 -1
  112. package/dist/cli/analysisViewCommands.js +36 -0
  113. package/dist/cli/artifactCommands.js +11 -12
  114. package/dist/cli/coreAnalysisCommands.js +3 -3
  115. package/dist/cli/coreBinaryCommands.js +32 -27
  116. package/dist/cli/coreNativeCommands.js +9 -10
  117. package/dist/cli/electronCommands.js +4 -4
  118. package/dist/cli/interactiveSetup.js +6 -6
  119. package/dist/cli/managedCommands.js +7 -8
  120. package/dist/cli/nativeCallCommands.js +1 -2
  121. package/dist/cli/omittableDefaults.js +50 -0
  122. package/dist/cli/processCommands.js +3 -2
  123. package/dist/cli/setupCommands.js +16 -15
  124. package/dist/cli/utilityCommands.js +9 -9
  125. package/dist/cli.js +16 -8
  126. package/dist/cliBrowserScenarioCommands.js +2 -2
  127. package/dist/cliCommandNames.js +1 -0
  128. package/dist/cliJsonInput.js +15 -1
  129. package/dist/cliOutput.js +0 -38
  130. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  131. package/dist/composition/binary.js +9 -9
  132. package/dist/composition/browserScenario.js +2 -1
  133. package/dist/composition/directAnalysis.js +20 -13
  134. package/dist/composition/electronScenario.js +1 -1
  135. package/dist/composition/optionalObservationProviders.js +12 -7
  136. package/dist/config/environment.js +6 -0
  137. package/dist/config/ghidraStartupTimeout.js +4 -9
  138. package/dist/config/homeDirectory.js +12 -0
  139. package/dist/config/mcpResponseBudget.js +9 -1
  140. package/dist/config/parseConfig.js +7 -3
  141. package/dist/config/parsers.js +19 -22
  142. package/dist/contracts/analysisViewToolContracts.js +56 -0
  143. package/dist/contracts/applicationToolContracts.js +5 -4
  144. package/dist/contracts/artifactComparisonExample.js +2 -2
  145. package/dist/contracts/artifactToolContracts.js +1 -1
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  147. package/dist/contracts/browserToolContracts.js +19 -15
  148. package/dist/contracts/enhancedInputs.js +2 -2
  149. package/dist/contracts/enhancedToolContracts.js +4 -3
  150. package/dist/contracts/evm/evmToolContracts.js +1 -1
  151. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  152. package/dist/contracts/inputSchemaPresentation.js +90 -0
  153. package/dist/contracts/investigationExamples.js +4 -3
  154. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  155. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  156. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  157. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  158. package/dist/contracts/managed/managedToolContracts.js +5 -10
  159. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  160. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  161. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  162. package/dist/contracts/native/nativeToolContracts.js +2 -2
  163. package/dist/contracts/officialToolContracts.js +2 -1
  164. package/dist/contracts/promptContracts.js +2 -2
  165. package/dist/contracts/providerSelection.js +1 -1
  166. package/dist/contracts/sessionToolContracts.js +14 -2
  167. package/dist/contracts/sessionToolSchemas.js +1 -14
  168. package/dist/contracts/toolContracts.js +2 -0
  169. package/dist/contracts/toolEffects.js +1 -0
  170. package/dist/contracts/toolOutputSchemaGroups.js +136 -92
  171. package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
  172. package/dist/contracts/toolSchemaMetadata.js +18 -69
  173. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  174. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  175. package/dist/contracts/webScriptToolContracts.js +1 -1
  176. package/dist/doctorRuntime.js +7 -5
  177. package/dist/domain/analysisErrorCore.js +3 -0
  178. package/dist/domain/analysisErrorPresentation.js +18 -3
  179. package/dist/domain/analysisErrorProjection.js +24 -5
  180. package/dist/domain/analysisSnapshot.js +29 -31
  181. package/dist/domain/analysisView/analysisView.js +243 -0
  182. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  183. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  184. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  185. package/dist/domain/android/androidApplication.js +1 -1
  186. package/dist/domain/apple/appleApplication.js +1 -1
  187. package/dist/domain/apple/dylibResolution.js +10 -3
  188. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  189. package/dist/domain/apple/keyedArchive.js +26 -2
  190. package/dist/domain/artifactComparison.js +15 -6
  191. package/dist/domain/artifactGraph.js +16 -3
  192. package/dist/domain/artifactInventoryEvidence.js +9 -16
  193. package/dist/domain/artifactOperationError.js +3 -3
  194. package/dist/domain/artifactPartialObservation.js +1 -0
  195. package/dist/domain/artifactPathSyntax.js +49 -0
  196. package/dist/domain/binaryTarget.js +39 -13
  197. package/dist/domain/browserCaptureComparison.js +13 -49
  198. package/dist/domain/browserNetworkEvidence.js +10 -4
  199. package/dist/domain/browserObservation.js +0 -1
  200. package/dist/domain/browserObservationSchemas.js +14 -3
  201. package/dist/domain/browserScenario.js +0 -1
  202. package/dist/domain/browserScenarioCapture.js +1 -2
  203. package/dist/domain/browserScenarioDiff.js +0 -2
  204. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  205. package/dist/domain/browserScenarioDiffValues.js +2 -2
  206. package/dist/domain/browserScenarioValues.js +3 -4
  207. package/dist/domain/callPath.js +8 -9
  208. package/dist/domain/callPathSchemas.js +2 -2
  209. package/dist/domain/changedBehavior.js +3 -3
  210. package/dist/domain/completionLedgerGeneration.js +2 -1
  211. package/dist/domain/configurationErrors.js +12 -0
  212. package/dist/domain/conformancePackage.js +4 -3
  213. package/dist/domain/evidence.js +10 -36
  214. package/dist/domain/evidenceBundle.js +7 -9
  215. package/dist/domain/evidenceCompletionLedger.js +2 -1
  216. package/dist/domain/functionComparison.js +4 -5
  217. package/dist/domain/functionComparisonDimensions.js +120 -87
  218. package/dist/domain/functionComparisonNormalization.js +23 -34
  219. package/dist/domain/functionComparisonResults.js +1 -4
  220. package/dist/domain/functionComparisonSchemas.js +2 -8
  221. package/dist/domain/functionDossierEvidence.js +2 -37
  222. package/dist/domain/javascript/electronActiveObservation.js +26 -69
  223. package/dist/domain/javascript/electronObservation.js +14 -3
  224. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  225. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  226. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  227. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  228. package/dist/domain/javascript/javascriptApplicationGraph.js +26 -3
  229. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  230. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  231. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  232. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  233. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  234. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  235. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  236. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  237. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  238. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  239. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  240. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  241. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  242. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  243. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  244. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  245. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  246. package/dist/domain/javascript/javascriptSemanticAnalysis.js +9 -3
  247. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  248. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  249. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  250. package/dist/domain/javascript/javascriptSemanticDataEffects.js +1 -1
  251. package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
  252. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  253. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  254. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  255. package/dist/domain/javascript/javascriptSemanticPrimitives.js +1 -12
  256. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  257. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  258. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  259. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  260. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  261. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  262. package/dist/domain/javascript/javascriptSemanticValues.js +47 -54
  263. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  264. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  265. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
  266. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  267. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  268. package/dist/domain/localPath.js +1 -1
  269. package/dist/domain/managed/managedArtifact.js +6 -4
  270. package/dist/domain/managed/managedMemberComparison.js +2 -9
  271. package/dist/domain/managed/managedNativeVerification.js +0 -2
  272. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  273. package/dist/domain/native/binaryLayout.js +2 -3
  274. package/dist/domain/native/nativeApiBoundary.js +1 -1
  275. package/dist/domain/native/nativeCallObservation.js +5 -3
  276. package/dist/domain/native/nativeInstruction.js +7 -0
  277. package/dist/domain/native/recordedCrash.js +2 -3
  278. package/dist/domain/offsetDateTime.js +17 -0
  279. package/dist/domain/process/processCapture.js +13 -12
  280. package/dist/domain/process/processCaptureCoverage.js +67 -0
  281. package/dist/domain/process/processCaptureExample.js +2 -1
  282. package/dist/domain/process/processCaptureParsing.js +1 -34
  283. package/dist/domain/process/processCaptureValidation.js +81 -13
  284. package/dist/domain/process/processComparison.js +41 -22
  285. package/dist/domain/process/processObservation.js +10 -2
  286. package/dist/domain/process/processScenario.js +24 -2
  287. package/dist/domain/process/processTraceComparison.js +0 -2
  288. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  289. package/dist/domain/process/processTraceEvaluation.js +15 -11
  290. package/dist/domain/process/processTraceSpecification.js +3 -4
  291. package/dist/domain/providerAdapterError.js +2 -0
  292. package/dist/domain/reconstructionCoverage.js +5 -2
  293. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  294. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  295. package/dist/domain/reconstructionVerification.js +3 -3
  296. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  297. package/dist/domain/referenceSourceGraph.js +20 -21
  298. package/dist/domain/staticRuntimeCorrelation.js +2 -2
  299. package/dist/domain/stringPatterns.js +6 -0
  300. package/dist/domain/swiftSymbolClassification.js +61 -0
  301. package/dist/domain/symbolAnalysis.js +66 -18
  302. package/dist/domain/webCaptureDiff.js +0 -1
  303. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  304. package/dist/domain/webEventListeners.js +3 -2
  305. package/dist/domain/webExecution.js +3 -2
  306. package/dist/domain/webRuntime.js +0 -2
  307. package/dist/domain/webScriptExport.js +1 -1
  308. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  309. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  310. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  311. package/dist/dotnet/ManagedMemberRows.js +75 -62
  312. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  313. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  314. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  315. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  316. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  317. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  318. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  319. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  320. package/dist/evaluation/CodexAgentEval.js +12 -8
  321. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  322. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  323. package/dist/firmware/FirmwareCommand.js +9 -5
  324. package/dist/firmware/FirmwareProvider.js +4 -4
  325. package/dist/generatedPackageMetadata.js +2 -2
  326. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  327. package/dist/ghidra/GhidraClient.js +91 -32
  328. package/dist/ghidra/GhidraClientStartup.js +0 -2
  329. package/dist/ghidra/GhidraDoctor.js +6 -5
  330. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  331. package/dist/ghidra/GhidraInstallation.js +40 -12
  332. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  333. package/dist/ghidra/GhidraLauncher.js +15 -7
  334. package/dist/ghidra/GhidraProvider.js +6 -2
  335. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  336. package/dist/ghidra/GhidraProviderClient.js +13 -3
  337. package/dist/ghidra/GhidraSessionError.js +2 -0
  338. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  339. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  340. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  341. package/dist/hopper/BridgeLauncher.js +34 -45
  342. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  343. package/dist/hopper/HopperCleanup.js +56 -27
  344. package/dist/hopper/HopperClient.js +86 -65
  345. package/dist/hopper/HopperMachOImage.js +3 -2
  346. package/dist/hopper/HopperProvider.js +16 -18
  347. package/dist/hopper/HopperRegexSearch.js +3 -6
  348. package/dist/hopper/HopperTargetLease.js +132 -49
  349. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  350. package/dist/ida/IdaConfiguration.js +8 -3
  351. package/dist/ida/IdaInput.js +1 -7
  352. package/dist/ida/IdaMcpConnection.js +8 -4
  353. package/dist/ida/IdaOperationRunner.js +3 -3
  354. package/dist/ida/IdaProvider.js +8 -12
  355. package/dist/ida/IdaSessionClient.js +20 -18
  356. package/dist/ida/IdaWorkspace.js +12 -13
  357. package/dist/inspector/V8InspectorCaptureProjection.js +1 -1
  358. package/dist/inspector/V8InspectorProvider.js +38 -28
  359. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  360. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  361. package/dist/main/shutdown.js +11 -3
  362. package/dist/main/startup.js +9 -2
  363. package/dist/main/transport.js +22 -2
  364. package/dist/main.js +11 -18
  365. package/dist/native/AppleMachoSelection.js +16 -6
  366. package/dist/native/CommandRunner.js +9 -7
  367. package/dist/native/LldbCallTracer.js +8 -2
  368. package/dist/native/NativeMacOSProvider.js +25 -15
  369. package/dist/native/NativeUiHelperRuntime.js +11 -2
  370. package/dist/native/NativeUiObservation.js +2 -2
  371. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  372. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  373. package/dist/process/ExecFileOutput.js +88 -6
  374. package/dist/process/PrivateRuntimeRoot.js +10 -5
  375. package/dist/process/ProcessOwnership.js +1 -4
  376. package/dist/process/ProcessOwnershipObservation.js +11 -5
  377. package/dist/process/ProviderProcess.js +1 -3
  378. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  379. package/dist/process/capture/ProcessCaptureError.js +13 -0
  380. package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
  381. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  382. package/dist/process/capture/ProcessHarness.js +21 -25
  383. package/dist/process/capture/ProcessNormalization.js +20 -2
  384. package/dist/process/capture/ProcessSampling.js +25 -2
  385. package/dist/process/capture/TerminalRenderer.js +14 -0
  386. package/dist/process/snapshotEnvironment.js +14 -0
  387. package/dist/server/EvidenceMcpServer.js +25 -14
  388. package/dist/server/createServer.js +49 -36
  389. package/dist/server/mcpClientMetadata.js +12 -5
  390. package/dist/server/promptCompletion.js +3 -8
  391. package/dist/server/registerAnalysisViewTool.js +15 -0
  392. package/dist/server/registerAndroidTools.js +2 -3
  393. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  394. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  395. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  396. package/dist/server/registerApplicationTools/coverage.js +1 -2
  397. package/dist/server/registerApplicationTools/helpers.js +1 -2
  398. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  399. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  400. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  401. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  402. package/dist/server/registerArtifactComparisonTool.js +4 -5
  403. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  404. package/dist/server/registerBrowserScenarioTool.js +3 -4
  405. package/dist/server/registerBrowserTools.js +13 -16
  406. package/dist/server/registerBundleComparisonTool.js +5 -6
  407. package/dist/server/registerCloseLifecycleTool.js +2 -3
  408. package/dist/server/registerElectronTools.js +10 -13
  409. package/dist/server/registerEnhancedTools.js +23 -23
  410. package/dist/server/registerEvidenceTools.js +3 -4
  411. package/dist/server/registerEvmTools.js +2 -3
  412. package/dist/server/registerFirmwareTools.js +2 -3
  413. package/dist/server/registerFunctionComparisonTool.js +7 -8
  414. package/dist/server/registerInvestigationTools.js +14 -15
  415. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  416. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  417. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  418. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  419. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  420. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  421. package/dist/server/registerOfficialTools.js +4 -19
  422. package/dist/server/registerProcessComparisonTool.js +8 -8
  423. package/dist/server/registerRecordedCrashTools.js +2 -3
  424. package/dist/server/registerSessionRecordTools.js +15 -19
  425. package/dist/server/registerSessionStatusTool.js +3 -4
  426. package/dist/server/registerSessionTools.js +12 -18
  427. package/dist/server/registerWebModuleTool.js +2 -3
  428. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  429. package/dist/server/registerWebRuntimeTools.js +4 -5
  430. package/dist/server/registerWebScriptTool.js +2 -3
  431. package/dist/server/registerWebSourceLocationTool.js +2 -3
  432. package/dist/server/toolResult.js +66 -94
  433. package/dist/server/toolResultEncoding.js +11 -10
  434. package/dist/windows/WindowsNativeLoader.js +1 -0
  435. package/dist/windows/WindowsOwnedProcess.js +60 -15
  436. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  437. package/native/windows/README.md +3 -1
  438. package/native/windows/build/manifest.json +2 -2
  439. package/native/windows/build/rea-windows-x64.node +0 -0
  440. package/package.json +39 -30
  441. package/scripts/rea.mjs +3 -6
  442. package/skills/reverse-engineer-anything/SKILL.md +9 -8
  443. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  444. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  445. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  446. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  447. package/dist/config.js +0 -1
  448. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  449. package/dist/contracts/process/processCaptureExample.js +0 -2
  450. package/dist/contracts/toolOutputSchemas.js +0 -2
  451. package/dist/main/reload.js +0 -12
  452. package/dist/main/state.js +0 -3
  453. package/dist/server/sessionToolPolicies.js +0 -2
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * ISO-8601 date-time that requires an explicit UTC offset.
4
+ *
5
+ * `z.string().datetime({ offset: true })` emits Zod's offset class as `[+-]`.
6
+ * Annex B and `u` mode accept that, but ECMA-262 `v` mode rejects the
7
+ * unescaped `-`, so any tool whose schema carries the pattern is unusable for a
8
+ * client that compiles advertised patterns — schema compilation happens before
9
+ * arguments are supplied, so the whole tools request fails rather than one call.
10
+ *
11
+ * The accepted set is identical to the Zod validator; only the offset class
12
+ * escapes `-`, as `\x2d`, because an escaped `-` inside a character class is
13
+ * removed by `oxlint --fix` as a useless escape.
14
+ */
15
+ export const offsetDateTimeSchema = z
16
+ .string()
17
+ .regex(/^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|(?:[+\x2d](?:[01]\d|2[0-3]):[0-5]\d)))$/u, "Use an ISO-8601 date-time with an explicit UTC offset");
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { jsonValueSchema } from "../jsonValue.js";
3
3
  import { normalizationSchema } from "./processScenario.js";
4
4
  import { collectProcessCaptureIssues } from "./processCaptureValidation.js";
5
- export * from "./processScenario.js";
5
+ import { processCaptureTruncationDetailsSchema, } from "./processCaptureCoverage.js";
6
6
  /** Capture collection whose members participate in global observation order. */
7
7
  export const PROCESS_CAPTURE_EVENT_COLLECTIONS = [
8
8
  "frames",
@@ -59,6 +59,13 @@ const fileEffectSchema = z.discriminatedUnion("status", [
59
59
  before: fileStateSchema,
60
60
  after: fileStateSchema,
61
61
  }),
62
+ z.object({
63
+ path: z.string(),
64
+ status: z.literal("unknown"),
65
+ before: fileStateSchema.nullable(),
66
+ after: fileStateSchema.nullable(),
67
+ reason: z.string().min(1),
68
+ }),
62
69
  ]);
63
70
  /** Exact serialized shape of a process capture. */
64
71
  const processSettlementSchema = z.discriminatedUnion("state", [
@@ -95,10 +102,6 @@ const processCaptureShapeSchema = z.strictObject({
95
102
  .string()
96
103
  .regex(/^[a-f0-9]{64}$/u)
97
104
  .nullable(),
98
- legacy_executable_sha256: z
99
- .string()
100
- .regex(/^[a-f0-9]{64}$/u)
101
- .optional(),
102
105
  executable_identity: z.strictObject({
103
106
  state: z.enum(["path_metadata_unchanged", "unknown"]),
104
107
  reason: z.string().nullable(),
@@ -110,6 +113,7 @@ const processCaptureShapeSchema = z.strictObject({
110
113
  sequence: z.number().int().nonnegative(),
111
114
  at_ms: z.number().int().nonnegative(),
112
115
  data: z.string(),
116
+ raw_data: z.string().optional(),
113
117
  })),
114
118
  rendered_frames: z.array(z.object({
115
119
  sequence: z.number().int().nonnegative(),
@@ -162,17 +166,16 @@ const processCaptureShapeSchema = z.strictObject({
162
166
  effects: z.array(fileEffectSchema),
163
167
  truncated: z.boolean(),
164
168
  })),
165
- event_journal: z
166
- .array(z.object({
169
+ event_journal: z.array(z.object({
167
170
  capture_order: z.number().int().nonnegative(),
168
171
  collection: z.enum(PROCESS_CAPTURE_EVENT_COLLECTIONS),
169
172
  index: z.number().int().nonnegative(),
170
- }))
171
- .default([]),
173
+ })),
172
174
  files_before: z.array(fileStateSchema),
173
175
  files_after: z.array(fileStateSchema),
174
176
  filesystem_effects: z.array(fileEffectSchema),
175
177
  truncated: z.boolean(),
178
+ truncation_details: processCaptureTruncationDetailsSchema.optional(),
176
179
  limitations: z.array(z.string()),
177
180
  residual_unknowns: z.array(z.object({
178
181
  scope: z.enum([
@@ -315,6 +318,4 @@ export const processCaptureSchema = processCaptureShapeSchema
315
318
  message: issue.message,
316
319
  });
317
320
  })
318
- .describe("The capture must preserve its canonical scenario, comparison, and normalization SHA-256 commitments; ordered capture timestamps and contiguous sequence numbers; before and final filesystem snapshots with truncation propagated; and exit-code consistency with deadline termination. When parsing older input without an event journal, REA supplies an empty journal; empty journals are valid. A non-empty journal must reference every captured observation exactly once with unique in-range references. These cross-field invariants are checked by REA after capture.");
319
- export { parseProcessCapture } from "./processCaptureParsing.js";
320
- export { compareProcessCaptures, comparisonStatusSchema, deriveProcessComparisonStatus, PROCESS_COMPARISON_DIMENSIONS, processCaptureComparisonSchema, } from "./processComparison.js";
321
+ .describe("The capture must preserve its canonical scenario, comparison, and normalization SHA-256 commitments; ordered capture timestamps and contiguous sequence numbers; before and final filesystem snapshots with truncation propagated; and exit-code consistency with deadline termination. The event journal is required; empty journals are valid. A non-empty journal must reference every captured observation exactly once with unique in-range references. These cross-field invariants are checked by REA after capture.");
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ const byteRetentionSchema = z.strictObject({
3
+ budget_bytes: z.number().int().nonnegative(),
4
+ observed_bytes: z.number().int().nonnegative(),
5
+ retained_bytes: z.number().int().nonnegative(),
6
+ observed_frames: z.number().int().nonnegative(),
7
+ retained_frames: z.number().int().nonnegative(),
8
+ });
9
+ /** Filesystem enumeration and whole-file digest coverage for one checkpoint. */
10
+ export const filesystemCoverageSchema = z.strictObject({
11
+ files_limit: z.number().int().nonnegative(),
12
+ depth_limit: z.number().int().nonnegative(),
13
+ enumeration_truncated: z.boolean(),
14
+ enumeration_reasons: z.array(z.enum(["files_limit", "depth_limit", "identity_changed"])),
15
+ hash_budget_bytes: z.number().int().nonnegative(),
16
+ hashed_bytes: z.number().int().nonnegative(),
17
+ hash_omissions: z.array(z.strictObject({
18
+ path: z.string(),
19
+ size_bytes: z.number().int().nonnegative(),
20
+ remaining_budget_bytes: z.number().int().nonnegative(),
21
+ reason: z.enum(["file_bytes_budget", "file_changed_or_short_read"]),
22
+ })),
23
+ });
24
+ /** Actual budget accounting; rendered bytes count state and visible lines, not JSON. */
25
+ export const processCaptureTruncationDetailsSchema = z.strictObject({
26
+ raw_terminal: byteRetentionSchema.describe("UTF-8 bytes of original PTY chunks; whole chunks are retained or omitted."),
27
+ rendered_terminal: byteRetentionSchema.describe("Cumulative UTF-8 bytes of serialized state plus visible lines, evaluated from retained PTY input; whole frames are retained or omitted."),
28
+ filesystem_before: filesystemCoverageSchema,
29
+ filesystem_after: filesystemCoverageSchema,
30
+ process: z.strictObject({
31
+ sample_limit: z.number().int().nonnegative(),
32
+ sampling_partial: z.boolean(),
33
+ retained_samples: z.number().int().nonnegative(),
34
+ sample_limit_reached: z.boolean(),
35
+ sampling_failures: z.number().int().nonnegative(),
36
+ first_sampling_failure: z.string().nullable(),
37
+ coverage: z.literal("sampled"),
38
+ }),
39
+ });
40
+ const omitted = (retention) => retention.observed_frames > retention.retained_frames;
41
+ const filesystemTruncated = (coverage) => coverage.enumeration_truncated || coverage.hash_omissions.length > 0;
42
+ /** Derive the legacy aggregate flag from independent producer observations. */
43
+ export const hasCaptureTruncation = (details) => omitted(details.raw_terminal) ||
44
+ omitted(details.rendered_terminal) ||
45
+ filesystemTruncated(details.filesystem_before) ||
46
+ filesystemTruncated(details.filesystem_after) ||
47
+ details.process.sampling_partial;
48
+ /** Older truncated captures lack enough information to localize missing observations. */
49
+ export const processSourceTruncated = (capture, source) => {
50
+ const details = capture.truncation_details;
51
+ if (details === undefined)
52
+ return capture.truncated;
53
+ switch (source) {
54
+ case "terminal_raw":
55
+ return omitted(details.raw_terminal);
56
+ case "terminal_rendered":
57
+ return (omitted(details.raw_terminal) || omitted(details.rendered_terminal));
58
+ case "filesystem":
59
+ return (filesystemTruncated(details.filesystem_before) ||
60
+ filesystemTruncated(details.filesystem_after));
61
+ case "process":
62
+ return details.process.sampling_partial;
63
+ case "interaction":
64
+ case "lifecycle":
65
+ return false;
66
+ }
67
+ };
@@ -1,4 +1,4 @@
1
- import { digestProcessCommitment } from "./processCapture.js";
1
+ import { digestProcessCommitment } from "./processScenario.js";
2
2
  const normalization = {
3
3
  paths: true,
4
4
  pids: true,
@@ -51,6 +51,7 @@ export const EMPTY_PROCESS_CAPTURE_EXAMPLE = {
51
51
  truncated: false,
52
52
  },
53
53
  ],
54
+ event_journal: [],
54
55
  files_before: [],
55
56
  files_after: [],
56
57
  filesystem_effects: [],
@@ -1,5 +1,4 @@
1
1
  import { processCaptureSchema, } from "./processCapture.js";
2
- import { z } from "zod";
3
2
  const verifiedCaptures = new WeakSet();
4
3
  const isVerifiedCapture = (capture) => verifiedCaptures.has(capture);
5
4
  const attachProof = (capture) => {
@@ -8,41 +7,9 @@ const attachProof = (capture) => {
8
7
  return capture;
9
8
  throw new TypeError("Process Capture proof ownership failed");
10
9
  };
11
- const recordSchema = z.record(z.string(), z.unknown());
12
- const LEGACY_EXECUTABLE_IDENTITY_REASON = "Legacy v3 capture did not distinguish selected and launch executable digests";
13
- const migrateLegacyV3Capture = (input) => {
14
- const capture = recordSchema.safeParse(input);
15
- if (!capture.success)
16
- return input;
17
- const manifest = recordSchema.safeParse(capture.data.manifest);
18
- if (!manifest.success)
19
- return input;
20
- if (manifest.data.provider_version !== "3" ||
21
- "selected_executable_sha256" in manifest.data ||
22
- "executable_identity" in manifest.data ||
23
- "legacy_executable_sha256" in manifest.data)
24
- return input;
25
- const { executable_sha256 } = manifest.data;
26
- if (typeof executable_sha256 !== "string" ||
27
- !/^[a-f0-9]{64}$/u.test(executable_sha256))
28
- return input;
29
- return {
30
- ...capture.data,
31
- manifest: {
32
- ...manifest.data,
33
- selected_executable_sha256: null,
34
- executable_sha256: null,
35
- executable_identity: {
36
- state: "unknown",
37
- reason: LEGACY_EXECUTABLE_IDENTITY_REASON,
38
- },
39
- legacy_executable_sha256: executable_sha256,
40
- },
41
- };
42
- };
43
10
  /** Parse unknown input and reject invalid commitments or semantics. */
44
11
  export const parseProcessCapture = (input) => {
45
- const parsed = processCaptureSchema.safeParse(migrateLegacyV3Capture(input));
12
+ const parsed = processCaptureSchema.safeParse(input);
46
13
  if (parsed.success)
47
14
  return attachProof(parsed.data);
48
15
  const issues = parsed.error.issues.flatMap((issue) => issue.code === "custom"
@@ -1,22 +1,13 @@
1
1
  import { digestProcessCommitment } from "./processScenario.js";
2
+ import { hasCaptureTruncation } from "./processCaptureCoverage.js";
2
3
  const orderedTimestamps = (values) => values.every((value, index) => {
3
4
  const previous = values[index - 1];
4
5
  return previous === undefined || value.at_ms >= previous.at_ms;
5
6
  });
6
7
  const validateCommitments = (capture, require) => {
7
8
  const { manifest } = capture;
8
- if (manifest.legacy_executable_sha256 !== undefined) {
9
- require(manifest.selected_executable_sha256 === null &&
10
- manifest.executable_sha256 === null &&
11
- manifest.executable_identity.state === "unknown" &&
12
- manifest.executable_identity.reason !== null &&
13
- manifest.scenario.executable_sha256 ===
14
- manifest.legacy_executable_sha256, "manifest.legacy_executable_sha256", "legacy executable digest must remain distinct from unknown selected and launch digests");
15
- }
16
- else {
17
- require(manifest.scenario.executable_sha256 ===
18
- manifest.selected_executable_sha256, "manifest.selected_executable_sha256", "selected executable commitment does not match the scenario projection");
19
- }
9
+ require(manifest.scenario.executable_sha256 ===
10
+ manifest.selected_executable_sha256, "manifest.selected_executable_sha256", "selected executable commitment does not match the scenario projection");
20
11
  require(manifest.executable_identity.state === "path_metadata_unchanged"
21
12
  ? manifest.executable_sha256 === manifest.selected_executable_sha256 &&
22
13
  manifest.executable_identity.reason === null
@@ -48,7 +39,7 @@ const validateOrdering = (capture, require) => {
48
39
  require(orderedTimestamps(values), name, "timestamps must be ordered");
49
40
  };
50
41
  const validateEventJournal = (capture, require) => {
51
- const journal = capture.event_journal ?? [];
42
+ const journal = capture.event_journal;
52
43
  if (journal.length === 0)
53
44
  return;
54
45
  const sizes = {
@@ -83,6 +74,82 @@ const validateLifecycle = (capture, require) => {
83
74
  capture.exit.code ===
84
75
  null, "exit", "deadline termination cannot declare a normal exit code");
85
76
  };
77
+ const validateCoverage = (capture, require) => {
78
+ const details = capture.truncation_details;
79
+ if (details === undefined)
80
+ return;
81
+ require(details.process.retained_samples === capture.process_samples.length &&
82
+ details.process.retained_samples <= details.process.sample_limit &&
83
+ details.process.sampling_partial ===
84
+ (details.process.sample_limit_reached ||
85
+ details.process.sampling_failures > 0) &&
86
+ (details.process.sampling_failures === 0) ===
87
+ (details.process.first_sampling_failure ===
88
+ null), "truncation_details.process", "sampling coverage must agree with retained samples and observed failures");
89
+ require(capture.truncated ===
90
+ hasCaptureTruncation(details), "truncation_details", "aggregate truncation must match producer coverage");
91
+ for (const [name, retention, count, bytes] of [
92
+ [
93
+ "raw_terminal",
94
+ details.raw_terminal,
95
+ capture.frames.length,
96
+ capture.frames.reduce((total, frame) => total + Buffer.byteLength(frame.raw_data ?? frame.data), 0),
97
+ ],
98
+ [
99
+ "rendered_terminal",
100
+ details.rendered_terminal,
101
+ capture.rendered_frames.length,
102
+ capture.rendered_frames.reduce((total, frame) => frame.lines.reduce((sum, line) => sum + Buffer.byteLength(line), total + Buffer.byteLength(frame.serialized_state)), 0),
103
+ ],
104
+ ]) {
105
+ // Whole frames are retained or omitted, so retained bytes are exactly the
106
+ // retained frames' bytes, and nothing is unretained when no frame was omitted.
107
+ require(retention.retained_frames === count &&
108
+ retention.observed_frames >= count &&
109
+ retention.retained_bytes === bytes &&
110
+ retention.observed_bytes >= retention.retained_bytes &&
111
+ (retention.observed_frames > count ||
112
+ retention.observed_bytes === retention.retained_bytes) &&
113
+ retention.retained_bytes <=
114
+ retention.budget_bytes, `truncation_details.${name}`, "retained observations and budget accounting do not agree");
115
+ }
116
+ for (const [name, coverage, files, checkpoint] of [
117
+ [
118
+ "filesystem_before",
119
+ details.filesystem_before,
120
+ capture.files_before,
121
+ capture.filesystem_checkpoints[0],
122
+ ],
123
+ [
124
+ "filesystem_after",
125
+ details.filesystem_after,
126
+ capture.files_after,
127
+ capture.filesystem_checkpoints[1],
128
+ ],
129
+ ]) {
130
+ const unhashedFiles = new Map(files
131
+ .filter((file) => file.type === "file" && file.sha256 === null)
132
+ .map((file) => [file.path, file]));
133
+ require(coverage.hash_omissions.length === unhashedFiles.size &&
134
+ new Set(coverage.hash_omissions.map(({ path }) => path)).size ===
135
+ unhashedFiles.size &&
136
+ coverage.hash_omissions.every((omission) => unhashedFiles.get(omission.path)?.size === omission.size_bytes &&
137
+ omission.remaining_budget_bytes <= coverage.hash_budget_bytes), `truncation_details.${name}.hash_omissions`, "every retained regular file without a digest must have one matching omission reason");
138
+ require(coverage.hashed_bytes ===
139
+ files
140
+ .filter((file) => file.type === "file" && file.sha256 !== null)
141
+ .reduce((sum, file) => sum + file.size, 0) &&
142
+ coverage.hashed_bytes <= coverage.hash_budget_bytes &&
143
+ files.length <=
144
+ coverage.files_limit, `truncation_details.${name}`, "filesystem budget accounting does not match retained observations");
145
+ require(coverage.enumeration_truncated ===
146
+ coverage.enumeration_reasons.length > 0 &&
147
+ checkpoint?.truncated ===
148
+ (coverage.enumeration_truncated ||
149
+ coverage.hash_omissions.length >
150
+ 0), `truncation_details.${name}`, "filesystem checkpoint truncation must match enumeration and digest coverage");
151
+ }
152
+ };
86
153
  /** Recompute commitments and cross-field invariants without side effects. */
87
154
  export const collectProcessCaptureIssues = (capture) => {
88
155
  const issues = [];
@@ -94,5 +161,6 @@ export const collectProcessCaptureIssues = (capture) => {
94
161
  validateOrdering(capture, require);
95
162
  validateEventJournal(capture, require);
96
163
  validateLifecycle(capture, require);
164
+ validateCoverage(capture, require);
97
165
  return issues;
98
166
  };
@@ -1,9 +1,13 @@
1
1
  import canonicalize from "canonicalize";
2
2
  import { z } from "zod";
3
+ import { processSourceTruncated } from "./processCaptureCoverage.js";
4
+ import { comparableTerminalFrame } from "./processObservation.js";
3
5
  import { AnalysisInputError } from "../analysisErrorCore.js";
4
6
  import { jsonValueSchema } from "../jsonValue.js";
5
- import { compareProcessTraces, processTraceOutcomesDiffer, processTraceComparisonResultSchema, } from "./processTraceComparison.js";
7
+ import {} from "./processTraceSpecification.js";
8
+ import { processTraceComparisonResultSchema } from "./processTraceEvaluation.js";
6
9
  import { dimensionsForTraceSources, traceCoversObservedDimension, } from "./processTraceDimensionProjection.js";
10
+ import { compareProcessTraces, processTraceOutcomesDiffer, } from "./processTraceComparison.js";
7
11
  const OPERATION = "compare_process_captures";
8
12
  /** Comparison classification that never equates incomplete evidence. */
9
13
  export const comparisonStatusSchema = z.enum([
@@ -72,7 +76,10 @@ export const processCaptureComparisonSchema = z
72
76
  });
73
77
  });
74
78
  const terminalObservations = (capture) => [
75
- ...capture.frames.map((frame) => ({ kind: "raw", ...frame })),
79
+ ...capture.frames.map((frame) => ({
80
+ kind: "raw",
81
+ ...comparableTerminalFrame(frame),
82
+ })),
76
83
  ...capture.rendered_frames.map((frame) => ({
77
84
  kind: "rendered",
78
85
  ...frame,
@@ -241,19 +248,23 @@ const applyTraceVerdict = (dimensions, specification, trace, captures) => {
241
248
  };
242
249
  };
243
250
  const compareDimensions = (left, right, sameNormalization) => {
244
- const classify = (scope, leftValues, rightValues) => !sameNormalization || hasUnknown(left, scope) || hasUnknown(right, scope)
251
+ const classify = (scope, leftValues, rightValues, source) => !sameNormalization ||
252
+ hasUnknown(left, scope) ||
253
+ hasUnknown(right, scope) ||
254
+ processSourceTruncated(left, source) ||
255
+ processSourceTruncated(right, source)
245
256
  ? "unknown"
246
257
  : classifyCollection(leftValues, rightValues);
247
258
  return {
248
- terminal: classify("terminal", terminalObservations(left), terminalObservations(right)),
249
- interaction: classify("interaction", left.interaction_events, right.interaction_events),
259
+ terminal: classify("terminal", terminalObservations(left), terminalObservations(right), "terminal_rendered"),
260
+ interaction: classify("interaction", left.interaction_events, right.interaction_events, "interaction"),
250
261
  exit: hasUnknown(left, "exit") || hasUnknown(right, "exit")
251
262
  ? "unknown"
252
263
  : sameJsonValue({ exit: left.exit, settlement: left.settlement }, { exit: right.exit, settlement: right.settlement })
253
264
  ? "unchanged"
254
265
  : "changed",
255
- filesystem: classify("filesystem", filesystemObservations(left), filesystemObservations(right)),
256
- process: classify("process", left.process_samples, right.process_samples),
266
+ filesystem: classify("filesystem", filesystemObservations(left), filesystemObservations(right), "filesystem"),
267
+ process: classify("process", left.process_samples, right.process_samples, "process"),
257
268
  };
258
269
  };
259
270
  /**
@@ -264,7 +275,8 @@ const compareDimensions = (left, right, sameNormalization) => {
264
275
  */
265
276
  export const compareProcessCaptures = (left, right, options = {}) => {
266
277
  assertComparable(left, right, options);
267
- if (left.truncated || right.truncated) {
278
+ if ((left.truncated && left.truncation_details === undefined) ||
279
+ (right.truncated && right.truncation_details === undefined)) {
268
280
  const truncated = truncatedComparison();
269
281
  return options.traceSpecification === undefined
270
282
  ? truncated
@@ -284,25 +296,32 @@ export const compareProcessCaptures = (left, right, options = {}) => {
284
296
  left,
285
297
  right,
286
298
  ]);
287
- const divergenceCandidates = PROCESS_COMPARISON_DIMENSIONS.map((dimension) => firstCollectionDivergence(dimension, processDimensionObservations(left, dimension), processDimensionObservations(right, dimension)));
299
+ const divergenceCandidates = PROCESS_COMPARISON_DIMENSIONS.map((dimension) => dimensions[dimension] === "unknown"
300
+ ? null
301
+ : firstCollectionDivergence(dimension, processDimensionObservations(left, dimension), processDimensionObservations(right, dimension)));
288
302
  const observedFirstDivergence = chooseFirstDivergence(divergenceCandidates.map((candidate) => candidate !== null &&
289
303
  trace?.verdict === "equivalent" &&
290
304
  dimensions[candidate.dimension] === "unchanged"
291
305
  ? null
292
306
  : candidate));
293
- const firstDivergence = trace?.verdict === "equivalent" &&
294
- deriveProcessComparisonStatus(PROCESS_COMPARISON_DIMENSIONS.map((dimension) => dimensions[dimension])) === "unchanged"
295
- ? { status: "none" }
296
- : observedFirstDivergence.status === "found"
297
- ? observedFirstDivergence
298
- : !sameNormalization ||
299
- left.residual_unknowns.length > 0 ||
300
- right.residual_unknowns.length > 0
301
- ? {
302
- status: "unknown",
303
- reason: "Residual unknowns prevent proving that no divergence occurred.",
304
- }
305
- : observedFirstDivergence;
307
+ const firstDivergence = left.truncated || right.truncated
308
+ ? {
309
+ status: "unknown",
310
+ reason: "Incomplete observations prevent locating the first divergence; unaffected dimensions retain their comparisons.",
311
+ }
312
+ : trace?.verdict === "equivalent" &&
313
+ deriveProcessComparisonStatus(PROCESS_COMPARISON_DIMENSIONS.map((dimension) => dimensions[dimension])) === "unchanged"
314
+ ? { status: "none" }
315
+ : observedFirstDivergence.status === "found"
316
+ ? observedFirstDivergence
317
+ : !sameNormalization ||
318
+ left.residual_unknowns.length > 0 ||
319
+ right.residual_unknowns.length > 0
320
+ ? {
321
+ status: "unknown",
322
+ reason: "Residual unknowns prevent proving that no divergence occurred.",
323
+ }
324
+ : observedFirstDivergence;
306
325
  const observedStatus = deriveProcessComparisonStatus(PROCESS_COMPARISON_DIMENSIONS.map((dimension) => dimensions[dimension]));
307
326
  return {
308
327
  status: observedStatus,
@@ -1,5 +1,11 @@
1
1
  import { z } from "zod";
2
2
  import { jsonValueSchema } from "../jsonValue.js";
3
+ /** Project normalized PTY facts without source text used only for audit. */
4
+ export const comparableTerminalFrame = (frame) => ({
5
+ sequence: frame.sequence,
6
+ at_ms: frame.at_ms,
7
+ data: frame.data,
8
+ });
3
9
  /** Process-capture observation families shared by live drivers and trace assertions. */
4
10
  export const processObservationSourceSchema = z.enum([
5
11
  "terminal_raw",
@@ -67,11 +73,13 @@ export const processObservationSubject = (source, value) => {
67
73
  const projectedRecord = (capture, location) => {
68
74
  const projected = (() => {
69
75
  switch (location.collection) {
70
- case "frames":
76
+ case "frames": {
77
+ const frame = capture.frames[location.index];
71
78
  return {
72
79
  source: "terminal_raw",
73
- value: capture.frames[location.index],
80
+ value: frame === undefined ? undefined : comparableTerminalFrame(frame),
74
81
  };
82
+ }
75
83
  case "rendered_frames":
76
84
  return {
77
85
  source: "terminal_rendered",
@@ -4,17 +4,36 @@ import { z } from "zod";
4
4
  const positiveBudget = z.number().int().safe().positive();
5
5
  const timedEventBase = { at_ms: z.number().int().safe().nonnegative() };
6
6
  const reservedRunIdEnvironmentName = "REA_PROCESS_RUN_ID";
7
+ const ENVIRONMENT_NAME_CHARACTER = "[^=\\u0000]";
8
+ /**
9
+ * Nonempty environment names other than the reserved run identifier. The
10
+ * exclusion is spelled as a complement instead of a negative look-ahead,
11
+ * because RE2 and Rust schema validators reject look-around and would refuse
12
+ * every tool in the advertised catalog.
13
+ */
14
+ const environmentNamePattern = (reserved) => {
15
+ // After the complete reserved name, at least one more character is needed.
16
+ let rest = `${ENVIRONMENT_NAME_CHARACTER}+`;
17
+ for (let index = reserved.length - 1; index >= 0; index -= 1) {
18
+ const character = reserved[index] ?? "";
19
+ // Diverge here, match the next reserved character, or (after a nonempty
20
+ // prefix) end the name early.
21
+ const choice = `[^=\\u0000${character}]${ENVIRONMENT_NAME_CHARACTER}*|${character}${rest}`;
22
+ rest = index === 0 ? choice : `(?:${choice})?`;
23
+ }
24
+ return new RegExp(`^(?:${rest})$`, "u");
25
+ };
7
26
  const environmentName = z
8
27
  .string()
9
28
  .min(1, "Environment names must not be empty")
10
- .regex(/^(?!REA_PROCESS_RUN_ID(?![\s\S]))[^=\0]+$/u, {
29
+ .regex(environmentNamePattern(reservedRunIdEnvironmentName), {
11
30
  error: (issue) => issue.input === reservedRunIdEnvironmentName
12
31
  ? `${reservedRunIdEnvironmentName} is reserved by the process adapter`
13
32
  : "Environment names cannot contain '=' or NUL",
14
33
  });
15
34
  const childProcessString = z
16
35
  .string()
17
- .regex(/^[^\0]*$/u, "Values passed to operating-system APIs cannot contain NUL");
36
+ .regex(/^[^\u0000]*$/u, "Values passed to operating-system APIs cannot contain NUL");
18
37
  export const normalizationSchema = z.object({
19
38
  paths: z.boolean(),
20
39
  pids: z.boolean(),
@@ -62,6 +81,9 @@ export const processComparisonContract = (scenario) => ({
62
81
  settle_ms: scenario.settle_ms,
63
82
  limits: scenario.limits,
64
83
  normalization: scenario.normalization,
84
+ ...(scenario.normalization.ports
85
+ ? { port_normalization_version: "contextual-endpoints-v2" }
86
+ : {}),
65
87
  });
66
88
  /**
67
89
  * Boundary schema for one bounded process experiment.
@@ -1,7 +1,5 @@
1
1
  import { evaluateProcessTraceSide, processTraceComparisonResultSchema, } from "./processTraceEvaluation.js";
2
2
  import { processTraceSpecificationSchema, } from "./processTraceSpecification.js";
3
- export { processTraceComparisonResultSchema, } from "./processTraceEvaluation.js";
4
- export { processTraceSpecificationSchema, } from "./processTraceSpecification.js";
5
3
  /** Compare two captures against an explicit finite trace language. */
6
4
  export const compareProcessTraces = (left, right, specificationInput) => {
7
5
  const specification = processTraceSpecificationSchema.parse(specificationInput);
@@ -1,4 +1,4 @@
1
- /** Map declared trace sources to legacy process-comparison dimensions. */
1
+ /** Map declared trace sources to process-comparison dimensions. */
2
2
  export const dimensionsForTraceSources = (sources) => {
3
3
  const dimensions = new Set();
4
4
  for (const source of sources) {
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
+ import { processSourceTruncated } from "./processCaptureCoverage.js";
2
3
  import { processObservationLocationSchema, projectProcessObservation, } from "./processObservation.js";
3
4
  import { canonicalTraceJson, comparableTracePayload, processTraceCardinalityBounds, } from "./processTraceSpecification.js";
4
- const identifierSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]{0,63}$/u);
5
- const locationSchema = processObservationLocationSchema;
5
+ const identifierSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._\x2d]{0,63}$/u);
6
6
  const matchedEventSchema = z.strictObject({
7
7
  event_id: identifierSchema,
8
- location: locationSchema,
8
+ location: processObservationLocationSchema,
9
9
  });
10
10
  const sideResultShape = {
11
11
  satisfied_constraints: z.array(z.string()),
@@ -36,7 +36,7 @@ const diagnosticSchema = z.strictObject({
36
36
  side: z.enum(["left", "right"]),
37
37
  message: z.string(),
38
38
  event_ids: z.array(identifierSchema),
39
- locations: z.array(locationSchema),
39
+ locations: z.array(processObservationLocationSchema),
40
40
  });
41
41
  /** Structured verdict for one declared process trace language. */
42
42
  export const processTraceComparisonResultSchema = z.strictObject({
@@ -56,11 +56,11 @@ const scopesFor = (sources) => new Set([...sources].map((source) => {
56
56
  return "process";
57
57
  return "interaction";
58
58
  }));
59
- const unknownSide = () => ({
59
+ const unknownSide = (rawTrace = []) => ({
60
60
  status: "unknown",
61
61
  matched_variant: null,
62
62
  satisfied_constraints: [],
63
- raw_trace: [],
63
+ raw_trace: rawTrace,
64
64
  });
65
65
  const failure = (input) => ({
66
66
  result: {
@@ -102,7 +102,7 @@ const evaluateFiniteTrace = (ids, specification) => {
102
102
  };
103
103
  const collectRecords = (capture, sources) => {
104
104
  const records = [];
105
- for (const location of capture.event_journal ?? []) {
105
+ for (const location of capture.event_journal) {
106
106
  const record = projectProcessObservation(capture, location);
107
107
  if (record !== null && sources.has(record.source))
108
108
  records.push({
@@ -296,10 +296,9 @@ const evaluateMatchedTrace = (trace, specification) => {
296
296
  export const evaluateProcessTraceSide = (capture, specification) => {
297
297
  const sources = new Set(specification.events.map(({ source }) => source));
298
298
  const relevantScopes = scopesFor(sources);
299
- if (capture.truncated ||
300
- capture.residual_unknowns.some(({ scope }) => relevantScopes.has(scope)))
301
- return { result: unknownSide(), diagnostic: null };
302
- if ((capture.event_journal ?? []).length === 0)
299
+ const incomplete = [...sources].some((source) => processSourceTruncated(capture, source)) ||
300
+ capture.residual_unknowns.some(({ scope }) => relevantScopes.has(scope));
301
+ if (capture.event_journal.length === 0)
303
302
  return {
304
303
  result: unknownSide(),
305
304
  diagnostic: {
@@ -310,6 +309,11 @@ export const evaluateProcessTraceSide = (capture, specification) => {
310
309
  },
311
310
  };
312
311
  const matched = matchRecords(collectRecords(capture, sources), specification);
312
+ if (incomplete)
313
+ return {
314
+ result: unknownSide("rawTrace" in matched ? matched.rawTrace : matched.result.raw_trace),
315
+ diagnostic: null,
316
+ };
313
317
  return "rawTrace" in matched
314
318
  ? evaluateMatchedTrace(matched, specification)
315
319
  : matched;
@@ -1,10 +1,9 @@
1
1
  import canonicalize from "canonicalize";
2
2
  import { z } from "zod";
3
+ import { IDENTIFIER_PATTERN } from "../stringPatterns.js";
3
4
  import { jsonValueSchema } from "../jsonValue.js";
4
5
  import { comparableProcessObservationPayload, processObservationSourceSchema, } from "./processObservation.js";
5
- const identifierSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
6
- /** Process observation families admitted by a declared trace specification. */
7
- export const processTraceSourceSchema = processObservationSourceSchema;
6
+ const identifierSchema = z.string().regex(IDENTIFIER_PATTERN);
8
7
  const cardinalitySchema = z.discriminatedUnion("kind", [
9
8
  z.strictObject({ kind: z.literal("required") }),
10
9
  z.strictObject({ kind: z.literal("optional") }),
@@ -25,7 +24,7 @@ const cardinalitySchema = z.discriminatedUnion("kind", [
25
24
  ]);
26
25
  const eventDeclarationSchema = z.strictObject({
27
26
  id: identifierSchema,
28
- source: processTraceSourceSchema,
27
+ source: processObservationSourceSchema,
29
28
  exact: jsonValueSchema,
30
29
  ignore_fields: z
31
30
  .array(z.enum([