rea-agents 6.1.0 → 6.3.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 (573) hide show
  1. package/README.md +24 -24
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +8 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +64 -36
  7. package/dist/android/JadxSession.js +51 -9
  8. package/dist/application/BinaryTargetResolver.js +68 -20
  9. package/dist/application/BrowserEvidence.js +3 -8
  10. package/dist/application/BrowserScenarioEvidence.js +4 -20
  11. package/dist/application/CapabilityInventory.js +43 -9
  12. package/dist/application/ClientConfigurationDocument.js +97 -25
  13. package/dist/application/ClientRegistrationStatus.js +19 -6
  14. package/dist/application/DirectAnalysis.js +41 -20
  15. package/dist/application/DirectAnalysisCleanup.js +71 -0
  16. package/dist/application/DirectAnalysisStatus.js +3 -7
  17. package/dist/application/Doctor.js +40 -53
  18. package/dist/application/DoctorDiagnostics.js +2 -3
  19. package/dist/application/EnhancedTools.js +51 -6
  20. package/dist/application/EvidenceBundleFiles.js +8 -3
  21. package/dist/application/InvestigationProviders.js +13 -5
  22. package/dist/application/JsonFiles.js +56 -23
  23. package/dist/application/LinuxHopper.js +11 -7
  24. package/dist/application/MacHopper.js +15 -18
  25. package/dist/application/RealHopperAssertions.js +0 -11
  26. package/dist/application/ReconstructionObligationCandidates.js +10 -3
  27. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  28. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  29. package/dist/application/RegularFileRead.js +17 -0
  30. package/dist/application/Setup.js +26 -23
  31. package/dist/application/SetupClientConfiguration.js +18 -7
  32. package/dist/application/SetupHost.js +20 -29
  33. package/dist/application/SetupPlan.js +24 -20
  34. package/dist/application/SetupSkill.js +57 -8
  35. package/dist/application/SupportedClients.js +43 -0
  36. package/dist/application/Uninstall.js +98 -30
  37. package/dist/application/UpdateMaintenance.js +13 -7
  38. package/dist/application/UpdateRuntime.js +12 -12
  39. package/dist/application/Utf8JsonInput.js +64 -0
  40. package/dist/application/WebScriptExportService.js +38 -5
  41. package/dist/application/WorkflowEvidence.js +25 -2
  42. package/dist/application/XrefsAddressResolution.js +45 -0
  43. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  44. package/dist/application/android/AndroidAnalysisService.js +1 -1
  45. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  46. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  47. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  48. package/dist/application/binary/AnalysisSnapshotCache.js +13 -10
  49. package/dist/application/binary/BinarySession.js +86 -29
  50. package/dist/application/binary/BinarySessionComposition.js +1 -3
  51. package/dist/application/binary/BinarySessionExecution.js +3 -5
  52. package/dist/application/binary/BinarySessionOpen.js +10 -2
  53. package/dist/application/binary/BinarySessionRecords.js +1 -1
  54. package/dist/application/binary/BinarySessionStatus.js +1 -6
  55. package/dist/application/binary/CompositeProvider.js +4 -18
  56. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  57. package/dist/application/binary/SessionProviderRouter.js +27 -135
  58. package/dist/application/homebrew.js +48 -0
  59. package/dist/application/javascript/ElectronActiveEvidence.js +10 -14
  60. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  61. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  62. package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
  63. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  64. package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
  65. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  66. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
  67. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
  68. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  69. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  70. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  71. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +46 -29
  72. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  73. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
  74. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
  75. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  76. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  77. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
  78. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  79. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  80. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
  81. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  82. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
  83. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  84. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
  85. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  86. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  87. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
  88. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
  89. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  90. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
  91. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
  92. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  93. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  94. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  95. package/dist/application/native/NativeCallRoutes.js +2 -4
  96. package/dist/application/process/ProcessCli.js +11 -11
  97. package/dist/application/process/ProcessEvidence.js +0 -1
  98. package/dist/artifacts/ArtifactProvider.js +53 -30
  99. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  100. package/dist/artifacts/ArtifactReader.js +31 -0
  101. package/dist/artifacts/AsarArtifactReader.js +81 -17
  102. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  103. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  104. package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
  105. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  106. package/dist/artifacts/SafeOutputTree.js +16 -2
  107. package/dist/artifacts/ZipArtifactReader.js +11 -4
  108. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  109. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  110. package/dist/artifacts/apple/KeyedArchiveReader.js +68 -42
  111. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  112. package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
  113. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
  114. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  115. package/dist/artifacts/inventory/classify.js +33 -14
  116. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  117. package/dist/artifacts/inventory/reader.js +3 -3
  118. package/dist/artifacts/inventory/scanCanonical.js +64 -34
  119. package/dist/artifacts/inventory/scanReader.js +12 -20
  120. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  121. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  122. package/dist/browser/CdpBrowserProvider.js +6 -6
  123. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  124. package/dist/browser/CdpCaptureEvents.js +0 -1
  125. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  126. package/dist/browser/CdpCaptureValues.js +20 -0
  127. package/dist/browser/CdpElectronInspection.js +2 -2
  128. package/dist/browser/CdpElectronProvider.js +4 -5
  129. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  130. package/dist/browser/CdpElectronScripts.js +4 -5
  131. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  132. package/dist/browser/CdpSafeMetadata.js +10 -10
  133. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  134. package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
  135. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  136. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  138. package/dist/browser/PlaywrightScenarioBrowser.js +269 -66
  139. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  140. package/dist/browser/PlaywrightScenarioSession.js +41 -32
  141. package/dist/browser/WebSourceMapFetcher.js +32 -6
  142. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  143. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  144. package/dist/browser/history/CaptureFailures.js +6 -2
  145. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  146. package/dist/catalogIdentity.js +0 -1
  147. package/dist/cli/analysisViewCommands.js +36 -0
  148. package/dist/cli/artifactCommands.js +11 -12
  149. package/dist/cli/coreAnalysisCommands.js +3 -3
  150. package/dist/cli/coreBinaryCommands.js +37 -28
  151. package/dist/cli/coreNativeCommands.js +9 -10
  152. package/dist/cli/electronCommands.js +12 -13
  153. package/dist/cli/interactiveSetup.js +6 -6
  154. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  155. package/dist/cli/jsonOutput.js +3 -2
  156. package/dist/cli/managedCommands.js +7 -8
  157. package/dist/cli/nativeCallCommands.js +1 -2
  158. package/dist/cli/omittableDefaults.js +50 -0
  159. package/dist/cli/processCommands.js +3 -2
  160. package/dist/cli/setupCommands.js +16 -15
  161. package/dist/cli/streamedJsonOutput.js +83 -4
  162. package/dist/cli/utilityCommands.js +10 -12
  163. package/dist/cli.js +19 -8
  164. package/dist/cliBrowserScenarioCommands.js +2 -2
  165. package/dist/cliCommandNames.js +1 -0
  166. package/dist/cliJsonFile.js +179 -0
  167. package/dist/cliJsonInput.js +60 -33
  168. package/dist/cliObservationOptions.js +4 -0
  169. package/dist/cliOutput.js +0 -38
  170. package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
  171. package/dist/composition/binary.js +9 -9
  172. package/dist/composition/browserScenario.js +2 -1
  173. package/dist/composition/directAnalysis.js +20 -14
  174. package/dist/composition/electronScenario.js +1 -1
  175. package/dist/composition/optionalObservationProviders.js +12 -7
  176. package/dist/config/environment.js +6 -0
  177. package/dist/config/ghidraStartupTimeout.js +4 -9
  178. package/dist/config/homeDirectory.js +12 -0
  179. package/dist/config/mcpResponseBudget.js +9 -1
  180. package/dist/config/parseConfig.js +7 -3
  181. package/dist/config/parsers.js +19 -22
  182. package/dist/contracts/analysisViewToolContracts.js +56 -0
  183. package/dist/contracts/applicationToolContracts.js +5 -4
  184. package/dist/contracts/artifactComparisonExample.js +7 -7
  185. package/dist/contracts/artifactToolContracts.js +1 -1
  186. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  187. package/dist/contracts/browserToolContracts.js +19 -15
  188. package/dist/contracts/enhancedInputs.js +2 -2
  189. package/dist/contracts/enhancedToolContracts.js +4 -3
  190. package/dist/contracts/errorSchemas.js +3 -1
  191. package/dist/contracts/evm/evmToolContracts.js +1 -1
  192. package/dist/contracts/functionComparisonExample.js +8 -0
  193. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  194. package/dist/contracts/inputSchemaPresentation.js +181 -0
  195. package/dist/contracts/investigationExamples.js +4 -3
  196. package/dist/contracts/javascript/electronToolContracts.js +3 -2
  197. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
  198. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
  199. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  200. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  201. package/dist/contracts/managed/managedToolContracts.js +8 -12
  202. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  203. package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
  204. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  205. package/dist/contracts/native/nativeToolContracts.js +2 -2
  206. package/dist/contracts/officialToolContracts.js +2 -1
  207. package/dist/contracts/promptContracts.js +2 -2
  208. package/dist/contracts/providerSelection.js +1 -1
  209. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  210. package/dist/contracts/sessionStatusContract.js +3 -2
  211. package/dist/contracts/sessionToolContracts.js +17 -4
  212. package/dist/contracts/sessionToolSchemas.js +4 -16
  213. package/dist/contracts/toolContracts.js +2 -0
  214. package/dist/contracts/toolEffects.js +1 -0
  215. package/dist/contracts/toolOutputSchemaGroups.js +138 -94
  216. package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
  217. package/dist/contracts/toolSchemaMetadata.js +18 -69
  218. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  219. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  220. package/dist/contracts/webScriptToolContracts.js +1 -1
  221. package/dist/doctorRuntime.js +7 -5
  222. package/dist/domain/analysisErrorBase.js +5 -0
  223. package/dist/domain/analysisErrorCore.js +3 -0
  224. package/dist/domain/analysisErrorPresentation.js +22 -5
  225. package/dist/domain/analysisErrorProjection.js +24 -5
  226. package/dist/domain/analysisSnapshot.js +31 -31
  227. package/dist/domain/analysisView/analysisView.js +241 -0
  228. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  229. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  230. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  231. package/dist/domain/android/androidApplication.js +1 -1
  232. package/dist/domain/android/androidPartialObservation.js +36 -0
  233. package/dist/domain/apple/appleApplication.js +1 -1
  234. package/dist/domain/apple/dylibResolution.js +10 -3
  235. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  236. package/dist/domain/apple/keyedArchive.js +26 -2
  237. package/dist/domain/artifactComparison.js +15 -6
  238. package/dist/domain/artifactGraph.js +17 -4
  239. package/dist/domain/artifactIdentity.js +8 -8
  240. package/dist/domain/artifactInspection.js +8 -8
  241. package/dist/domain/artifactInventoryEvidence.js +9 -16
  242. package/dist/domain/artifactOperationError.js +3 -3
  243. package/dist/domain/artifactPartialObservation.js +1 -0
  244. package/dist/domain/artifactPathSyntax.js +49 -0
  245. package/dist/domain/binaryTarget.js +39 -13
  246. package/dist/domain/browserCaptureComparison.js +13 -49
  247. package/dist/domain/browserCompleteness.js +3 -2
  248. package/dist/domain/browserNetworkEvidence.js +10 -4
  249. package/dist/domain/browserObservation.js +0 -1
  250. package/dist/domain/browserObservationSchemas.js +14 -3
  251. package/dist/domain/browserScenario.js +0 -1
  252. package/dist/domain/browserScenarioCapture.js +1 -2
  253. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  254. package/dist/domain/browserScenarioDiff.js +0 -2
  255. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  256. package/dist/domain/browserScenarioDiffValues.js +2 -2
  257. package/dist/domain/browserScenarioNormalization.js +3 -3
  258. package/dist/domain/browserScenarioValues.js +6 -6
  259. package/dist/domain/callPath.js +15 -18
  260. package/dist/domain/callPathSchemas.js +2 -2
  261. package/dist/domain/canonicalDigest.js +7 -1
  262. package/dist/domain/canonicalOrdering.js +1 -13
  263. package/dist/domain/changedBehavior.js +5 -6
  264. package/dist/domain/comparisonSemantics.js +0 -5
  265. package/dist/domain/completionLedgerGeneration.js +2 -1
  266. package/dist/domain/configurationErrors.js +12 -0
  267. package/dist/domain/conformancePackage.js +4 -3
  268. package/dist/domain/digests.js +0 -3
  269. package/dist/domain/evidence.js +19 -40
  270. package/dist/domain/evidenceBundle.js +58 -42
  271. package/dist/domain/evidenceCompletionLedger.js +2 -1
  272. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  273. package/dist/domain/functionComparison.js +6 -6
  274. package/dist/domain/functionComparisonDimensions.js +120 -87
  275. package/dist/domain/functionComparisonNormalization.js +26 -36
  276. package/dist/domain/functionComparisonResults.js +3 -6
  277. package/dist/domain/functionComparisonSchemas.js +2 -8
  278. package/dist/domain/functionDossierEvidence.js +4 -38
  279. package/dist/domain/hopperValues.js +11 -15
  280. package/dist/domain/javascript/electronActiveObservation.js +29 -71
  281. package/dist/domain/javascript/electronObservation.js +14 -3
  282. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
  283. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
  284. package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
  285. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  286. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  287. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  288. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
  289. package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
  290. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  291. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  292. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  293. package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
  294. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
  295. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  296. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  297. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  298. package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
  299. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  300. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
  301. package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
  302. package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
  303. package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
  304. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  305. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  306. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
  307. package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
  308. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  309. package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
  310. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  311. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  312. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  313. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  314. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  315. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
  316. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
  317. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  318. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  319. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  320. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
  321. package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
  322. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  323. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  324. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  325. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
  326. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  327. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  328. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  329. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  330. package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
  331. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  332. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  333. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  334. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
  335. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  336. package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
  337. package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
  338. package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
  339. package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
  340. package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
  341. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  342. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  343. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  344. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  345. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  346. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  347. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  348. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  349. package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
  350. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  351. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  352. package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
  353. package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
  354. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  355. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  356. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  357. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
  358. package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
  359. package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
  360. package/dist/domain/jsonSerialization.js +109 -55
  361. package/dist/domain/jsonShape.js +46 -19
  362. package/dist/domain/localPath.js +10 -4
  363. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  364. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  365. package/dist/domain/managed/managedArtifact.js +6 -4
  366. package/dist/domain/managed/managedMemberComparison.js +2 -9
  367. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  368. package/dist/domain/managed/managedNativeVerification.js +0 -2
  369. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  370. package/dist/domain/native/binaryLayout.js +2 -3
  371. package/dist/domain/native/nativeApiBoundary.js +1 -1
  372. package/dist/domain/native/nativeCallObservation.js +3 -3
  373. package/dist/domain/native/nativeInstruction.js +7 -0
  374. package/dist/domain/native/nativeValueFlow.js +5 -11
  375. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  376. package/dist/domain/native/recordedCrash.js +2 -3
  377. package/dist/domain/offsetDateTime.js +17 -0
  378. package/dist/domain/process/processCapture.js +22 -20
  379. package/dist/domain/process/processCaptureCoverage.js +70 -0
  380. package/dist/domain/process/processCaptureExample.js +45 -1
  381. package/dist/domain/process/processCaptureParsing.js +1 -34
  382. package/dist/domain/process/processCaptureValidation.js +82 -13
  383. package/dist/domain/process/processComparison.js +39 -43
  384. package/dist/domain/process/processObservation.js +10 -2
  385. package/dist/domain/process/processScenario.js +24 -2
  386. package/dist/domain/process/processTraceComparison.js +0 -2
  387. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  388. package/dist/domain/process/processTraceEvaluation.js +19 -15
  389. package/dist/domain/process/processTraceSpecification.js +4 -7
  390. package/dist/domain/providerAdapterError.js +2 -0
  391. package/dist/domain/providerCleanupError.js +6 -2
  392. package/dist/domain/reconstructionCoverage.js +7 -3
  393. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  394. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  395. package/dist/domain/reconstructionUnknowns.js +4 -3
  396. package/dist/domain/reconstructionVerification.js +6 -5
  397. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  398. package/dist/domain/referenceSourceGraph.js +27 -28
  399. package/dist/domain/referenceSourceImportParsing.js +34 -45
  400. package/dist/domain/residualUnknown.js +3 -2
  401. package/dist/domain/staticRuntimeCorrelation.js +4 -3
  402. package/dist/domain/stringPatterns.js +6 -0
  403. package/dist/domain/swiftSymbolClassification.js +66 -0
  404. package/dist/domain/symbolAnalysis.js +83 -20
  405. package/dist/domain/unicodeCodePointOrder.js +6 -0
  406. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  407. package/dist/domain/webCaptureDiff.js +71 -30
  408. package/dist/domain/webCaptureDiffSchemas.js +8 -11
  409. package/dist/domain/webEventListeners.js +3 -2
  410. package/dist/domain/webExecution.js +3 -2
  411. package/dist/domain/webInventory.js +3 -2
  412. package/dist/domain/webMcpDiscovery.js +4 -3
  413. package/dist/domain/webRuntime.js +0 -2
  414. package/dist/domain/webScriptExport.js +2 -2
  415. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  416. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  417. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  418. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  419. package/dist/dotnet/ManagedMemberRows.js +75 -62
  420. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  421. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  422. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  423. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  424. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  425. package/dist/dotnet/ManagedStaticProvider.js +13 -12
  426. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  427. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  428. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  429. package/dist/evaluation/CodexAgentEval.js +12 -8
  430. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  431. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  432. package/dist/filesystem/RegularFile.js +41 -0
  433. package/dist/firmware/FirmwareCommand.js +9 -5
  434. package/dist/firmware/FirmwareProvider.js +4 -4
  435. package/dist/generatedPackageMetadata.js +2 -2
  436. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  437. package/dist/ghidra/GhidraClient.js +105 -36
  438. package/dist/ghidra/GhidraClientStartup.js +0 -2
  439. package/dist/ghidra/GhidraDoctor.js +6 -5
  440. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  441. package/dist/ghidra/GhidraInstallation.js +151 -22
  442. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  443. package/dist/ghidra/GhidraLauncher.js +58 -26
  444. package/dist/ghidra/GhidraProvider.js +6 -2
  445. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  446. package/dist/ghidra/GhidraProviderClient.js +13 -3
  447. package/dist/ghidra/GhidraSessionError.js +2 -0
  448. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  449. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  450. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  451. package/dist/hopper/BridgeLauncher.js +34 -45
  452. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  453. package/dist/hopper/HopperCleanup.js +56 -27
  454. package/dist/hopper/HopperClient.js +86 -65
  455. package/dist/hopper/HopperMachOImage.js +3 -2
  456. package/dist/hopper/HopperProvider.js +16 -18
  457. package/dist/hopper/HopperRegexSearch.js +3 -6
  458. package/dist/hopper/HopperTargetLease.js +132 -49
  459. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  460. package/dist/ida/IdaConfiguration.js +8 -3
  461. package/dist/ida/IdaInput.js +1 -7
  462. package/dist/ida/IdaMcpConnection.js +8 -4
  463. package/dist/ida/IdaOperationRunner.js +5 -3
  464. package/dist/ida/IdaProvider.js +8 -12
  465. package/dist/ida/IdaSessionClient.js +24 -20
  466. package/dist/ida/IdaWorkspace.js +12 -13
  467. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  468. package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
  469. package/dist/inspector/V8InspectorProvider.js +97 -35
  470. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  471. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  472. package/dist/main/shutdown.js +81 -29
  473. package/dist/main/startup.js +9 -2
  474. package/dist/main/transport.js +23 -3
  475. package/dist/main.js +11 -18
  476. package/dist/native/AppleMachoSelection.js +16 -6
  477. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  478. package/dist/native/AppleObjcProperties.js +17 -7
  479. package/dist/native/CommandRunner.js +9 -7
  480. package/dist/native/LldbCallTracer.js +249 -77
  481. package/dist/native/NativeMacOSProvider.js +32 -17
  482. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  483. package/dist/native/NativeUiHelperRuntime.js +11 -2
  484. package/dist/native/NativeUiObservation.js +2 -2
  485. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  486. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  487. package/dist/process/ExecFileOutput.js +88 -6
  488. package/dist/process/PrivateRuntimeRoot.js +10 -5
  489. package/dist/process/ProcessOwnership.js +1 -4
  490. package/dist/process/ProcessOwnershipObservation.js +18 -16
  491. package/dist/process/ProviderProcess.js +1 -3
  492. package/dist/process/capture/FilesystemSnapshot.js +131 -24
  493. package/dist/process/capture/ProcessCaptureError.js +13 -0
  494. package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
  495. package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
  496. package/dist/process/capture/ProcessHarness.js +16 -33
  497. package/dist/process/capture/ProcessNormalization.js +20 -2
  498. package/dist/process/capture/ProcessSampling.js +25 -2
  499. package/dist/process/capture/TerminalRenderer.js +14 -0
  500. package/dist/process/snapshotEnvironment.js +14 -0
  501. package/dist/server/EvidenceMcpServer.js +25 -14
  502. package/dist/server/analysisAdmission.js +8 -0
  503. package/dist/server/createServer.js +71 -59
  504. package/dist/server/mcpClientMetadata.js +12 -5
  505. package/dist/server/promptCompletion.js +3 -8
  506. package/dist/server/registerAnalysisViewTool.js +15 -0
  507. package/dist/server/registerAndroidTools.js +2 -3
  508. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -6
  509. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  510. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  511. package/dist/server/registerApplicationTools/coverage.js +1 -2
  512. package/dist/server/registerApplicationTools/helpers.js +4 -4
  513. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  514. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  515. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  516. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  517. package/dist/server/registerArtifactComparisonTool.js +4 -5
  518. package/dist/server/registerArtifactTools.js +2 -2
  519. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  520. package/dist/server/registerBrowserScenarioTool.js +3 -4
  521. package/dist/server/registerBrowserTools.js +13 -16
  522. package/dist/server/registerBundleComparisonTool.js +5 -6
  523. package/dist/server/registerCloseLifecycleTool.js +8 -7
  524. package/dist/server/registerElectronTools.js +10 -13
  525. package/dist/server/registerEnhancedTools.js +82 -77
  526. package/dist/server/registerEvidenceTools.js +54 -47
  527. package/dist/server/registerEvmTools.js +2 -3
  528. package/dist/server/registerFirmwareTools.js +2 -3
  529. package/dist/server/registerFunctionComparisonTool.js +7 -8
  530. package/dist/server/registerInvestigationTools.js +14 -15
  531. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  532. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  533. package/dist/server/registerManagedTools.js +7 -4
  534. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  535. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  536. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  537. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  538. package/dist/server/registerOfficialTools.js +32 -41
  539. package/dist/server/registerProcessComparisonTool.js +8 -8
  540. package/dist/server/registerRecordedCrashTools.js +2 -3
  541. package/dist/server/registerSessionRecordTools.js +15 -19
  542. package/dist/server/registerSessionStatusTool.js +3 -4
  543. package/dist/server/registerSessionTools.js +19 -19
  544. package/dist/server/registerWebModuleTool.js +2 -3
  545. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  546. package/dist/server/registerWebRuntimeTools.js +4 -5
  547. package/dist/server/registerWebScriptTool.js +2 -3
  548. package/dist/server/registerWebSourceLocationTool.js +2 -3
  549. package/dist/server/toolResult.js +66 -94
  550. package/dist/server/toolResultEncoding.js +11 -10
  551. package/dist/windows/WindowsNativeLoader.js +1 -0
  552. package/dist/windows/WindowsOwnedProcess.js +60 -15
  553. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  554. package/native/windows/README.md +3 -1
  555. package/native/windows/build/manifest.json +2 -2
  556. package/native/windows/build/rea-windows-x64.node +0 -0
  557. package/package.json +42 -30
  558. package/scripts/rea.mjs +3 -6
  559. package/skills/reverse-engineer-anything/SKILL.md +14 -13
  560. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  561. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  562. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  563. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +18 -0
  564. package/dist/artifacts/inventory/policy.js +0 -2
  565. package/dist/config.js +0 -1
  566. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  567. package/dist/contracts/process/processCaptureExample.js +0 -2
  568. package/dist/contracts/toolOutputSchemas.js +0 -2
  569. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  570. package/dist/main/reload.js +0 -12
  571. package/dist/main/state.js +0 -3
  572. package/dist/server/registerNativeTools.js +0 -6
  573. package/dist/server/sessionToolPolicies.js +0 -2
@@ -3,18 +3,22 @@ import { constants, statSync } from "node:fs";
3
3
  import { open, mkdtemp, rm, stat } from "node:fs/promises";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
- import { digestProcessCommitment, parseProcessCapture, partialProcessCaptureObservationSchema, processComparisonContract, processScenarioCommitment, } from "../../domain/process/processCapture.js";
6
+ import { setTimeout as delay } from "node:timers/promises";
7
+ import { digestProcessCommitment, processComparisonContract, processScenarioCommitment, } from "../../domain/process/processScenario.js";
8
+ import { parseProcessCapture } from "../../domain/process/processCaptureParsing.js";
7
9
  import { PRODUCT_IDENTITY } from "../../identity.js";
8
10
  import { snapshotRoots } from "./FilesystemSnapshot.js";
9
11
  import { classifyFilesystemEffects } from "./ProcessFilesystemEffects.js";
10
12
  import { cleanupOwnedProcessGroup, verifyNoTokenOwnedProcesses, } from "../ProcessOwnership.js";
11
13
  import { observeOwnedProcessGroup, prepareProcessOwnershipInspection, systemProcessOwnershipHost, } from "../ProcessOwnershipObservation.js";
12
- import { describeProcessCaptureExecutionFailure, ProcessCaptureError, } from "./ProcessCaptureError.js";
14
+ import { describeProcessCaptureExecutionFailure, normalizeCaptureFailure, ProcessCaptureError, } from "./ProcessCaptureError.js";
13
15
  import { assertNotCancelled } from "./ProcessScenarioRuntimeValidation.js";
14
16
  import { normalizeProcessElapsedTime, normalizeProcessSamples, normalizeProcessText, } from "./ProcessNormalization.js";
15
17
  import { PROCESS_PROVIDER } from "../../domain/process/processEvidenceProvider.js";
16
18
  import { TerminalRenderer } from "./TerminalRenderer.js";
19
+ import { hasCaptureTruncation, } from "../../domain/process/processCaptureCoverage.js";
17
20
  import { scheduleProcessInterval } from "./ProcessTimer.js";
21
+ import { partialProcessCaptureObservationSchema } from "../../domain/process/processCapture.js";
18
22
  /** Seed explicit observation availability before capture completion begins. */
19
23
  export const createProcessCaptureObservationBuffer = (options) => ({
20
24
  target_pid: {
@@ -39,10 +43,7 @@ export const createProcessCaptureObservationBuffer = (options) => ({
39
43
  filesystem_snapshots: {
40
44
  before: {
41
45
  state: "available",
42
- value: {
43
- files: options.before.files,
44
- truncated: options.before.truncated,
45
- },
46
+ value: options.before,
46
47
  },
47
48
  after: {
48
49
  state: "unavailable",
@@ -92,6 +93,10 @@ export const buildCaptureResult = (options) => {
92
93
  const sensitiveInputUnknown = "Sensitive scripted input values are redacted from process capture Evidence.";
93
94
  const filesystemObservationUnknown = "No filesystem observation paths were selected; filesystem effects remain unknown.";
94
95
  const hasFilesystemObservations = options.scenario.filesystem_observation_paths.length > 0;
96
+ const filesystemEffects = classifyFilesystemEffects(options.before, options.after);
97
+ const filesystemUnknowns = [
98
+ ...new Set(filesystemEffects.flatMap((effect) => effect.status === "unknown" ? [effect.reason] : [])),
99
+ ];
95
100
  return {
96
101
  manifest: options.manifest,
97
102
  normalization: options.scenario.normalization,
@@ -111,8 +116,9 @@ export const buildCaptureResult = (options) => {
111
116
  event_journal: options.eventJournal,
112
117
  files_before: options.before.files,
113
118
  files_after: options.after.files,
114
- filesystem_effects: classifyFilesystemEffects(options.before.files, options.after.files),
115
- truncated: options.truncated,
119
+ filesystem_effects: filesystemEffects,
120
+ truncated: hasCaptureTruncation(options.truncationDetails),
121
+ truncation_details: options.truncationDetails,
116
122
  limitations: [
117
123
  "The executable digest is a prelaunch file sample; matching path metadata immediately after spawn does not prove an atomic operating-system image binding.",
118
124
  "Process trees are sampled and may omit short-lived descendants.",
@@ -122,6 +128,8 @@ export const buildCaptureResult = (options) => {
122
128
  "Filesystem observations are before/after snapshots, not syscall traces.",
123
129
  "Inherited host environment variables are not recorded and may affect results.",
124
130
  ...(!hasFilesystemObservations ? [filesystemObservationUnknown] : []),
131
+ ...filesystemUnknowns,
132
+ ...captureCoverageUnknowns(options.truncationDetails).map(({ reason }) => reason),
125
133
  ...(hasSensitiveScriptedInput ? [sensitiveInputUnknown] : []),
126
134
  ],
127
135
  residual_unknowns: [
@@ -149,12 +157,52 @@ export const buildCaptureResult = (options) => {
149
157
  },
150
158
  ]
151
159
  : []),
160
+ ...filesystemUnknowns.map((reason) => ({
161
+ scope: "filesystem",
162
+ reason,
163
+ })),
152
164
  ...(hasSensitiveScriptedInput
153
165
  ? [{ scope: "interaction", reason: sensitiveInputUnknown }]
154
166
  : []),
167
+ ...captureCoverageUnknowns(options.truncationDetails).filter(({ scope }) => scope !== "terminal"),
155
168
  ],
156
169
  };
157
170
  };
171
+ const captureCoverageUnknowns = (details) => {
172
+ const unknowns = [];
173
+ if (details.raw_terminal.observed_frames > details.raw_terminal.retained_frames)
174
+ unknowns.push({
175
+ scope: "terminal",
176
+ reason: "Raw PTY chunks exceeded output_bytes and were omitted; rendered states also lack those inputs. See truncation_details.raw_terminal.",
177
+ });
178
+ if (details.rendered_terminal.observed_frames >
179
+ details.rendered_terminal.retained_frames)
180
+ unknowns.push({
181
+ scope: "terminal",
182
+ reason: "Cumulative rendered state and visible-line bytes exceeded output_bytes; whole rendered frames were omitted. Raw PTY coverage is reported separately. See truncation_details.rendered_terminal.",
183
+ });
184
+ for (const [name, coverage] of [
185
+ ["before", details.filesystem_before],
186
+ ["after_settlement", details.filesystem_after],
187
+ ]) {
188
+ if (coverage.enumeration_truncated)
189
+ unknowns.push({
190
+ scope: "filesystem",
191
+ reason: `Filesystem ${name} path enumeration was incomplete: ${coverage.enumeration_reasons.join(", ")}. See truncation_details.`,
192
+ });
193
+ if (coverage.hash_omissions.length > 0)
194
+ unknowns.push({
195
+ scope: "filesystem",
196
+ reason: `Filesystem ${name} omitted ${String(coverage.hash_omissions.length)} whole-file digests; per-path reasons and remaining file_bytes budget are in truncation_details.`,
197
+ });
198
+ }
199
+ if (details.process.sampling_partial)
200
+ unknowns.push({
201
+ scope: "process",
202
+ reason: "Process sampling stopped with incomplete observations; sample_limit is reported in truncation_details.process.",
203
+ });
204
+ return unknowns;
205
+ };
158
206
  const identityFromStats = (stats) => ({
159
207
  dev: stats.dev,
160
208
  ino: stats.ino,
@@ -301,7 +349,8 @@ export const createRunManifest = async (scenario, startedAt, completedAt, execut
301
349
  normalization_sha256: digestProcessCommitment(scenario.normalization),
302
350
  };
303
351
  };
304
- export const observeSettlement = async (runId, processGroupIds, settleMs, recordEvent = () => undefined, platform = process.platform) => {
352
+ export const observeSettlement = async (runId, processGroupIds, settleMs, recordEvent = () => undefined, platform = process.platform, signal) => {
353
+ assertNotCancelled(signal);
305
354
  if (platform === "win32") {
306
355
  recordEvent("lifecycle", 1);
307
356
  return { state: "unverifiable", elapsed_ms: 0 };
@@ -310,11 +359,9 @@ export const observeSettlement = async (runId, processGroupIds, settleMs, record
310
359
  let consecutiveEmpty = 0;
311
360
  let deadlineReached = false;
312
361
  while (!deadlineReached) {
313
- const observations = await Promise.all([...new Set(processGroupIds)].map((processGroupId) => observeOwnedProcessGroup({
314
- runId,
315
- leaderPid: processGroupId,
316
- processGroupId,
317
- })));
362
+ assertNotCancelled(signal);
363
+ const observations = await Promise.all([...new Set(processGroupIds)].map((processGroupId) => observeOwnedProcessGroup({ runId, leaderPid: processGroupId, processGroupId }, undefined, signal)));
364
+ assertNotCancelled(signal);
318
365
  if (observations.some(({ state }) => state === "unverifiable")) {
319
366
  recordEvent("lifecycle", 1);
320
367
  return { state: "unverifiable", elapsed_ms: Date.now() - started };
@@ -331,7 +378,7 @@ export const observeSettlement = async (runId, processGroupIds, settleMs, record
331
378
  deadlineReached = Date.now() - started >= settleMs;
332
379
  if (deadlineReached)
333
380
  break;
334
- await new Promise((resolve) => setTimeout(resolve, 50));
381
+ await delay(50, undefined, { signal });
335
382
  }
336
383
  recordEvent("lifecycle", 1);
337
384
  return { state: "alive_at_deadline", elapsed_ms: Date.now() - started };
@@ -403,6 +450,50 @@ const verifyTokenOwnedProcessesUntilSettled = async (verify) => {
403
450
  }
404
451
  return result;
405
452
  };
453
+ const releaseCapturedProcessGroup = async (ownership, host) => {
454
+ if (host.platform === "win32")
455
+ return {
456
+ state: "unverified",
457
+ reason: "owned process cleanup is unverifiable on Windows without process-job authority",
458
+ };
459
+ let outcome = {
460
+ state: "cleaned",
461
+ reason: null,
462
+ };
463
+ const unverified = [];
464
+ try {
465
+ const cleaned = await host.cleanupProcessGroup(ownership);
466
+ unverified.push(...(cleaned.unverified ?? []));
467
+ if (!cleaned.cleaned) {
468
+ outcome = { state: "unverified", reason: cleaned.reason };
469
+ }
470
+ else {
471
+ const verified = await verifyTokenOwnedProcessesUntilSettled(() => host.verifyTokenOwnedProcesses(ownership.runId, undefined, ownership.captureBaseline, ownership));
472
+ unverified.push(...(verified.unverified ?? []));
473
+ if (!verified.cleaned)
474
+ outcome = { state: "unverified", reason: verified.reason };
475
+ }
476
+ }
477
+ catch (cause) {
478
+ outcome = {
479
+ state: "failed",
480
+ reason: cause instanceof Error
481
+ ? cause.message || cause.name || "owned process cleanup failed"
482
+ : "owned process cleanup failed",
483
+ };
484
+ }
485
+ return unverified.length === 0
486
+ ? outcome
487
+ : {
488
+ ...outcome,
489
+ unverified_processes: [
490
+ ...new Map(unverified.map(({ pid, diagnostic }) => [
491
+ `${String(pid)}:${diagnostic}`,
492
+ { pid, reason: diagnostic },
493
+ ])).values(),
494
+ ],
495
+ };
496
+ };
406
497
  export const releaseProcessResources = async (options) => {
407
498
  const host = options.host ?? processCaptureCleanupHost;
408
499
  for (const timer of options.timers)
@@ -422,60 +513,20 @@ export const releaseProcessResources = async (options) => {
422
513
  : "renderer dispose failed",
423
514
  };
424
515
  }
425
- let ownedProcessGroup = {
426
- state: options.terminal === undefined ? "not_required" : "cleaned",
427
- reason: null,
428
- };
429
- if (options.terminal !== undefined) {
430
- if (host.platform === "win32") {
431
- ownedProcessGroup = {
432
- state: "unverified",
433
- reason: "owned process cleanup is unverifiable on Windows without process-job authority",
434
- };
435
- }
436
- else {
437
- const terminalPid = options.terminal.pid;
438
- const relation = {
439
- leaderPid: terminalPid,
440
- processGroupId: terminalPid,
441
- ...(options.sampledProcessGroupIds === undefined
442
- ? {}
443
- : { sampledProcessGroupIds: options.sampledProcessGroupIds }),
444
- };
445
- const cleaned = await host.cleanupProcessGroup({
446
- runId: options.runId,
447
- leaderPid: terminalPid,
448
- processGroupId: terminalPid,
449
- sweepTokenOwnedProcesses: true,
450
- ...(options.sampledProcessGroupIds === undefined
451
- ? {}
452
- : { sampledProcessGroupIds: options.sampledProcessGroupIds }),
453
- ...(options.captureBaseline === undefined
454
- ? {}
455
- : { captureBaseline: options.captureBaseline }),
456
- });
457
- const unverified = [...(cleaned.unverified ?? [])];
458
- if (!cleaned.cleaned) {
459
- ownedProcessGroup = { state: "unverified", reason: cleaned.reason };
460
- }
461
- else {
462
- const verified = await verifyTokenOwnedProcessesUntilSettled(() => host.verifyTokenOwnedProcesses(options.runId, undefined, options.captureBaseline, relation));
463
- unverified.push(...(verified.unverified ?? []));
464
- if (!verified.cleaned)
465
- ownedProcessGroup = { state: "unverified", reason: verified.reason };
466
- }
467
- if (unverified.length > 0)
468
- ownedProcessGroup = {
469
- ...ownedProcessGroup,
470
- unverified_processes: [
471
- ...new Map(unverified.map(({ pid, diagnostic }) => [
472
- `${String(pid)}:${diagnostic}`,
473
- { pid, reason: diagnostic },
474
- ])).values(),
475
- ],
476
- };
477
- }
478
- }
516
+ const ownedProcessGroup = options.terminal === undefined
517
+ ? { state: "not_required", reason: null }
518
+ : await releaseCapturedProcessGroup({
519
+ runId: options.runId,
520
+ leaderPid: options.terminal.pid,
521
+ processGroupId: options.terminal.pid,
522
+ sweepTokenOwnedProcesses: true,
523
+ ...(options.sampledProcessGroupIds === undefined
524
+ ? {}
525
+ : { sampledProcessGroupIds: options.sampledProcessGroupIds }),
526
+ ...(options.captureBaseline === undefined
527
+ ? {}
528
+ : { captureBaseline: options.captureBaseline }),
529
+ }, host);
479
530
  let temporaryRoot = {
480
531
  state: "cleaned",
481
532
  reason: null,
@@ -507,12 +558,14 @@ export const cleanupReportFailure = (report) => {
507
558
  };
508
559
  export const captureTerminalFrames = (options) => {
509
560
  let outputBytes = 0;
510
- let truncated = false;
561
+ let observedBytes = 0;
562
+ let observedFrames = 0;
511
563
  options.terminal.onData((data) => {
512
564
  options.onOutput();
513
565
  const bytes = Buffer.byteLength(data);
566
+ observedBytes += bytes;
567
+ observedFrames += 1;
514
568
  if (outputBytes + bytes > options.scenario.limits.output_bytes) {
515
- truncated = true;
516
569
  return;
517
570
  }
518
571
  outputBytes += bytes;
@@ -523,11 +576,18 @@ export const captureTerminalFrames = (options) => {
523
576
  sequence,
524
577
  at_ms: atMs,
525
578
  data: normalized,
579
+ ...(normalized === data ? {} : { raw_data: data }),
526
580
  });
527
581
  options.renderer.write(data, atMs);
528
582
  options.recordEvent("frames", sequence);
529
583
  });
530
- return () => truncated;
584
+ return () => ({
585
+ budget_bytes: options.scenario.limits.output_bytes,
586
+ observed_bytes: observedBytes,
587
+ retained_bytes: outputBytes,
588
+ observed_frames: observedFrames,
589
+ retained_frames: options.frames.length,
590
+ });
531
591
  };
532
592
  export const resolveProcessResult = (capture, executionFailure, cleanup, observations, partialContext) => {
533
593
  const cleanupFailure = cleanupReportFailure(cleanup);
@@ -660,16 +720,30 @@ export const prepareProcessCapture = async (scenario, signal, captureSnapshot =
660
720
  await host.prepareOwnershipInspector?.(signal);
661
721
  assertNotCancelled(signal);
662
722
  const before = await captureSnapshot(scenario, signal);
723
+ const runId = randomUUID();
663
724
  const temporaryRoot = await host.createTemporaryRoot();
664
725
  try {
665
726
  assertNotCancelled(signal);
666
- const runId = randomUUID();
667
727
  const ownershipBaseline = (await host.captureOwnershipBaseline?.(signal)) ?? [];
668
728
  assertNotCancelled(signal);
669
729
  return { temporaryRoot, runId, ownershipBaseline, before };
670
730
  }
671
731
  catch (cause) {
672
- await host.cleanup(temporaryRoot);
732
+ const cleanup = await releaseProcessResources({
733
+ timers: new Set(),
734
+ terminal: undefined,
735
+ renderer: undefined,
736
+ runId,
737
+ temporaryRoot,
738
+ host: { ...processCaptureCleanupHost, removeTemporaryRoot: host.cleanup },
739
+ });
740
+ resolveProcessResult(undefined, normalizeCaptureFailure(cause, signal), cleanup, createProcessCaptureObservationBuffer({
741
+ frames: [],
742
+ interactions: [],
743
+ samples: [],
744
+ eventJournal: [],
745
+ before,
746
+ }), { scenario });
673
747
  throw cause;
674
748
  }
675
749
  };
@@ -1,12 +1,42 @@
1
- /** Classify path-stable filesystem effects between two bounded states. */
1
+ import { sep } from "node:path";
2
+ const unobservedAbsenceReason = (path, phase, completeRoots, filesByPath) => {
3
+ const alias = path.slice(0, path.indexOf(":"));
4
+ if (!completeRoots.has(alias))
5
+ return `The ${phase} snapshot did not exhaust path enumeration under ${alias}; absence remains unknown.`;
6
+ const rootPath = `${alias}:.`;
7
+ if (path !== rootPath && filesByPath.get(rootPath)?.type === "symlink")
8
+ return `The ${phase} snapshot did not follow the symbolic link at ${rootPath}; descendant absence remains unknown.`;
9
+ for (let index = path.lastIndexOf(sep); index > 0; index = path.lastIndexOf(sep, index - 1)) {
10
+ const parent = path.slice(0, index);
11
+ if (filesByPath.get(parent)?.type === "symlink")
12
+ return `The ${phase} snapshot did not follow the symbolic link at ${parent}; descendant absence remains unknown.`;
13
+ }
14
+ return undefined;
15
+ };
16
+ /** Classify effects only from observed path absence, metadata, and content hashes. */
2
17
  export const classifyFilesystemEffects = (before, after) => {
3
- const beforeByPath = new Map(before.map((file) => [file.path, file]));
4
- const afterByPath = new Map(after.map((file) => [file.path, file]));
18
+ const beforeByPath = new Map(before.files.map((file) => [file.path, file]));
19
+ const afterByPath = new Map(after.files.map((file) => [file.path, file]));
20
+ const beforeCompleteRoots = new Set(before.completeRoots);
21
+ const afterCompleteRoots = new Set(after.completeRoots);
5
22
  return [...new Set([...beforeByPath.keys(), ...afterByPath.keys()])]
6
23
  .sort()
7
24
  .map((path) => {
8
25
  const beforeFile = beforeByPath.get(path) ?? null;
9
26
  const afterFile = afterByPath.get(path) ?? null;
27
+ const reason = beforeFile === null
28
+ ? unobservedAbsenceReason(path, "before", beforeCompleteRoots, beforeByPath)
29
+ : afterFile === null
30
+ ? unobservedAbsenceReason(path, "after", afterCompleteRoots, afterByPath)
31
+ : undefined;
32
+ if (reason !== undefined)
33
+ return {
34
+ path,
35
+ status: "unknown",
36
+ before: beforeFile,
37
+ after: afterFile,
38
+ reason,
39
+ };
10
40
  if (beforeFile === null) {
11
41
  if (afterFile === null)
12
42
  throw new TypeError(`Filesystem effect ${path} has no file state`);
@@ -24,11 +54,26 @@ export const classifyFilesystemEffects = (before, after) => {
24
54
  before: beforeFile,
25
55
  after: null,
26
56
  };
57
+ const metadataChanged = beforeFile.type !== afterFile.type ||
58
+ beforeFile.mode !== afterFile.mode ||
59
+ beforeFile.size !== afterFile.size ||
60
+ beforeFile.symlink_target !== afterFile.symlink_target;
61
+ if (!metadataChanged &&
62
+ beforeFile.type === "file" &&
63
+ afterFile.type === "file" &&
64
+ (beforeFile.sha256 === null || afterFile.sha256 === null))
65
+ return {
66
+ path,
67
+ status: "unknown",
68
+ before: beforeFile,
69
+ after: afterFile,
70
+ reason: "A file content hash is unavailable in at least one snapshot; matching metadata does not establish unchanged contents.",
71
+ };
27
72
  return {
28
73
  path,
29
- status: JSON.stringify(beforeFile) === JSON.stringify(afterFile)
30
- ? "unchanged"
31
- : "modified",
74
+ status: metadataChanged || beforeFile.sha256 !== afterFile.sha256
75
+ ? "modified"
76
+ : "unchanged",
32
77
  before: beforeFile,
33
78
  after: afterFile,
34
79
  };
@@ -1,9 +1,8 @@
1
- import { parseProcessCapture } from "../../domain/process/processCapture.js";
1
+ import { parseProcessCapture } from "../../domain/process/processCaptureParsing.js";
2
2
  import { err, ok } from "../../domain/result.js";
3
3
  import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
4
4
  import {} from "../../domain/analysisErrorBase.js";
5
- import { describeProcessCaptureExecutionFailure, ProcessCaptureError, processCaptureCancelled, } from "./ProcessCaptureError.js";
6
- export { ProcessCaptureError } from "./ProcessCaptureError.js";
5
+ import { describeProcessCaptureExecutionFailure, ProcessCaptureError, normalizeCaptureFailure, processCaptureCancelled, } from "./ProcessCaptureError.js";
7
6
  import { startProcessSampler } from "./ProcessSampling.js";
8
7
  import { snapshotRoots } from "./FilesystemSnapshot.js";
9
8
  import { TerminalRenderer } from "./TerminalRenderer.js";
@@ -15,14 +14,11 @@ import { createProcessCaptureJournal, scheduleScenarioInteractions, } from "./Pr
15
14
  import { makeProcessCaptureEnvironment } from "./ProcessCaptureEnvironment.js";
16
15
  import { classifyFilesystemEffects } from "./ProcessFilesystemEffects.js";
17
16
  import { processCaptureOwnershipUnavailableReason } from "./ProcessCaptureCapability.js";
18
- import { DarwinProcessOwnershipInspectionError } from "../DarwinProcessRunTokenReader.js";
19
- export { probeProcessCaptureCapability } from "./ProcessCaptureCapability.js";
20
17
  const cleanupFailedStartup = async (options) => {
21
18
  const sampledProcessGroupIds = options.terminal !== undefined &&
22
19
  options.observations?.process_samples.state === "available"
23
20
  ? selectCapturedProcessGroupIds(options.terminal.pid, options.observations.process_samples.value).filter((groupId) => groupId !== options.terminal?.pid)
24
21
  : undefined;
25
- options.terminal?.kill("SIGKILL");
26
22
  if (options.observations !== undefined && options.renderer !== undefined) {
27
23
  try {
28
24
  options.observations.rendered_frames = {
@@ -89,7 +85,7 @@ const startCaptureRuntime = async (options) => {
89
85
  value: scenario.normalization.pids ? 1 : terminal.pid,
90
86
  };
91
87
  const executableIdentity = observeLaunchedExecutable(scenario.executable, selectedExecutable);
92
- const framesTruncated = captureTerminalFrames({
88
+ const rawTerminalRetention = captureTerminalFrames({
93
89
  ...options,
94
90
  terminal,
95
91
  started,
@@ -117,7 +113,7 @@ const startCaptureRuntime = async (options) => {
117
113
  startedAt,
118
114
  executableIdentity,
119
115
  lastOutput: () => lastOutput,
120
- framesTruncated,
116
+ rawTerminalRetention,
121
117
  stopSampler,
122
118
  };
123
119
  }
@@ -181,18 +177,6 @@ const finishProcessRun = async (options) => {
181
177
  : { scenario: options.scenario, rootPid };
182
178
  return resolveProcessResult(cleanupFailure === undefined ? verifiedCapture : capture, executionFailure, cleanup, options.observations, partialContext);
183
179
  };
184
- /** Preserve typed process-inspection preflight failures at the capture boundary. */
185
- export const normalizeCaptureFailure = (cause, signal) => {
186
- if (cause instanceof ProcessCaptureError)
187
- return cause;
188
- if (cause instanceof DarwinProcessOwnershipInspectionError)
189
- return new ProcessCaptureError(cause.message, { cause });
190
- if (signal?.aborted === true &&
191
- (cause === signal.reason ||
192
- (cause instanceof Error && cause.name === "AbortError")))
193
- return processCaptureCancelled();
194
- return cause;
195
- };
196
180
  const completeCapture = async (options) => {
197
181
  const unavailableReason = (stage, cause) => `${stage} failed: ${cause instanceof Error ? cause.message : "unknown failure"}`;
198
182
  const { runtime, scenario } = options;
@@ -201,7 +185,7 @@ const completeCapture = async (options) => {
201
185
  throw processCaptureCancelled();
202
186
  let settlement;
203
187
  try {
204
- settlement = await observeSettlement(options.runId, selectCapturedProcessGroupIds(runtime.terminal.pid, options.samples), scenario.settle_ms, options.recordEvent, options.hostPlatform);
188
+ settlement = await observeSettlement(options.runId, selectCapturedProcessGroupIds(runtime.terminal.pid, options.samples), scenario.settle_ms, options.recordEvent, options.hostPlatform, options.signal);
205
189
  }
206
190
  catch (cause) {
207
191
  options.observationBuffer.settlement = {
@@ -214,7 +198,8 @@ const completeCapture = async (options) => {
214
198
  state: "available",
215
199
  value: settlement,
216
200
  };
217
- const samplingPartial = (await runtime.stopSampler()).partial;
201
+ const sampling = await runtime.stopSampler();
202
+ const samplingPartial = sampling.partial;
218
203
  await settleProcessCaptureJournal(options.eventJournal);
219
204
  assertNotCancelled(options.signal);
220
205
  let after;
@@ -235,7 +220,7 @@ const completeCapture = async (options) => {
235
220
  ...options.observationBuffer.filesystem_snapshots,
236
221
  after: {
237
222
  state: "available",
238
- value: { files: after.files, truncated: after.truncated },
223
+ value: after,
239
224
  },
240
225
  };
241
226
  options.recordEvent("filesystem_checkpoints", 1);
@@ -266,7 +251,7 @@ const completeCapture = async (options) => {
266
251
  name: "after_settlement",
267
252
  at_ms: Math.max(0, Date.now() - runtime.started),
268
253
  files: after.files,
269
- effects: classifyFilesystemEffects(options.before.files, after.files),
254
+ effects: classifyFilesystemEffects(options.before, after),
270
255
  truncated: after.truncated,
271
256
  },
272
257
  ];
@@ -282,19 +267,19 @@ const completeCapture = async (options) => {
282
267
  throw cause;
283
268
  }
284
269
  options.observationBuffer.manifest = { state: "available", value: manifest };
285
- const truncated = options.initiallyTruncated ||
286
- after.truncated ||
287
- runtime.framesTruncated() ||
288
- checkpoints.some(({ truncated: partial }) => partial) ||
289
- samplingPartial ||
290
- runtime.renderer.truncated();
291
270
  return buildCaptureResult({
292
271
  frames: options.frames,
293
272
  exit: { ...options.exit, reason },
294
273
  samples: options.samples,
295
274
  before: options.before,
296
275
  after,
297
- truncated,
276
+ truncationDetails: {
277
+ raw_terminal: runtime.rawTerminalRetention(),
278
+ rendered_terminal: runtime.renderer.retention(),
279
+ filesystem_before: options.before.coverage,
280
+ filesystem_after: after.coverage,
281
+ process: sampling.coverage,
282
+ },
298
283
  scenario,
299
284
  rootPid: runtime.terminal.pid,
300
285
  samplingPartial,
@@ -380,7 +365,6 @@ const runProcessScenario = async (scenario, signal, hostEnvironment = process.en
380
365
  samples,
381
366
  interactions,
382
367
  exit,
383
- initiallyTruncated: before.truncated,
384
368
  eventJournal,
385
369
  observationBuffer: observations,
386
370
  recordEvent,
@@ -389,7 +373,6 @@ const runProcessScenario = async (scenario, signal, hostEnvironment = process.en
389
373
  });
390
374
  }
391
375
  catch (cause) {
392
- runtime?.terminal.kill("SIGKILL");
393
376
  executionFailure = normalizeCaptureFailure(cause, signal);
394
377
  if (runtime !== undefined &&
395
378
  observations.rendered_frames.state === "unavailable" &&
@@ -1,3 +1,4 @@
1
+ import { isIP } from "node:net";
1
2
  /** Bucket one elapsed process-capture timestamp under scenario normalization. */
2
3
  export const normalizeProcessElapsedTime = (elapsedMs, timeBucketMs) => Math.floor(elapsedMs / timeBucketMs) * timeBucketMs;
3
4
  /** Normalize one terminal/protocol payload under explicitly selected scenario rules. */
@@ -10,14 +11,31 @@ export const normalizeProcessText = (value, scenario, temporaryRoot, pid) => {
10
11
  for (const [index, root] of scenario.filesystem_observation_paths.entries())
11
12
  normalized = normalized.replaceAll(root, `<filesystem-root-${String(index)}>`);
12
13
  }
14
+ if (scenario.normalization.ports)
15
+ normalized = normalizePortTokens(normalized);
13
16
  if (scenario.normalization.pids)
14
17
  normalized = normalizePidTokens(normalized, [pid]);
15
- if (scenario.normalization.ports)
16
- normalized = normalized.replaceAll(/(?<=[:=])\d{2,5}\b/g, "<port>");
17
18
  for (const pattern of scenario.normalization.patterns)
18
19
  normalized = normalized.replaceAll(pattern.pattern, pattern.replacement);
19
20
  return normalized;
20
21
  };
22
+ // A port may end a sentence, but a period followed by a letter, digit, or
23
+ // underscore in any script continues a decimal, version, or host name and is
24
+ // not a port boundary.
25
+ // PTY chunks are normalized independently, so a period that ends the chunk
26
+ // stays unnormalized: its continuation may arrive in the next chunk.
27
+ const normalizePortTokens = (value) => {
28
+ const endpointNormalized = value.replaceAll(/(\b[a-z][a-z0-9+.-]*:\/\/[^\s/?#"'<>]+|\blocalhost|\b(?:\d{1,3}\.){3}\d{1,3}|\[[\da-f:.%]+\]):(\d{1,5})(?![\p{L}\p{N}_@:]|\.(?:[\p{L}\p{N}_]|$))/giu, (match, endpoint, port) => {
29
+ if (Number(port) > 65_535)
30
+ return match;
31
+ const isEndpoint = endpoint.includes("://")
32
+ ? URL.canParse(`${endpoint}:${port}`)
33
+ : endpoint.toLowerCase() === "localhost" ||
34
+ isIP(endpoint.replace(/^\[|\]$/gu, "")) !== 0;
35
+ return isEndpoint ? `${endpoint}:<port>` : match;
36
+ });
37
+ return endpointNormalized.replaceAll(/(\b(?:port|tcp_port|udp_port|listen)\b["']?\s*[:=]\s*)(\d{1,5})(?![\p{L}\p{N}_]|\.(?:[\p{L}\p{N}_]|$))/giu, (match, prefix, port) => Number(port) <= 65_535 ? `${prefix}<port>` : match);
38
+ };
21
39
  /** Project sampled observations under the caller-selected normalization rules. */
22
40
  export const normalizeProcessSamples = (samples, scenario, rootPid) => {
23
41
  const identifiers = [
@@ -328,6 +328,9 @@ export const startProcessSampler = (options) => {
328
328
  let stopped = false;
329
329
  let abortCurrent;
330
330
  let partial = false;
331
+ let limitReached = false;
332
+ let samplingFailures = 0;
333
+ let firstSamplingFailure = null;
331
334
  let rootInitialized = false;
332
335
  const sample = () => {
333
336
  if (stopped || pending !== undefined)
@@ -363,6 +366,7 @@ export const startProcessSampler = (options) => {
363
366
  continue;
364
367
  if (samples.length >= limit) {
365
368
  partial = true;
369
+ limitReached = true;
366
370
  continue;
367
371
  }
368
372
  lastObservations.set(value.pid, observation);
@@ -372,8 +376,16 @@ export const startProcessSampler = (options) => {
372
376
  }
373
377
  })
374
378
  .catch((cause) => {
375
- if (!(cause instanceof Error && cause.name === "AbortError"))
379
+ if (!(cause instanceof Error && cause.name === "AbortError")) {
376
380
  partial = true;
381
+ samplingFailures += 1;
382
+ firstSamplingFailure ??=
383
+ cause instanceof Error
384
+ ? `${cause.name}: ${cause.message}`
385
+ : typeof cause === "string"
386
+ ? cause
387
+ : `Unexpected sampling rejection (${typeof cause})`;
388
+ }
377
389
  })
378
390
  .then(() => {
379
391
  abortCurrent = undefined;
@@ -387,6 +399,17 @@ export const startProcessSampler = (options) => {
387
399
  clearInterval(timer);
388
400
  abortCurrent?.();
389
401
  await pending;
390
- return { partial };
402
+ return {
403
+ partial,
404
+ coverage: {
405
+ sample_limit: limit,
406
+ sampling_partial: partial,
407
+ retained_samples: samples.length,
408
+ sample_limit_reached: limitReached,
409
+ sampling_failures: samplingFailures,
410
+ first_sampling_failure: firstSamplingFailure,
411
+ coverage: "sampled",
412
+ },
413
+ };
391
414
  };
392
415
  };