rea-agents 6.2.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 (297) hide show
  1. package/README.md +18 -20
  2. package/bridge/hopper_bridge.py +2 -0
  3. package/dist/android/JadxProvider.js +8 -2
  4. package/dist/android/JadxSession.js +51 -9
  5. package/dist/application/BinaryTargetResolver.js +63 -17
  6. package/dist/application/BrowserScenarioEvidence.js +2 -2
  7. package/dist/application/ClientConfigurationDocument.js +28 -0
  8. package/dist/application/ClientRegistrationStatus.js +19 -6
  9. package/dist/application/DirectAnalysis.js +12 -6
  10. package/dist/application/DirectAnalysisCleanup.js +0 -1
  11. package/dist/application/DirectAnalysisStatus.js +2 -5
  12. package/dist/application/Doctor.js +25 -34
  13. package/dist/application/DoctorDiagnostics.js +1 -1
  14. package/dist/application/EvidenceBundleFiles.js +1 -1
  15. package/dist/application/InvestigationProviders.js +4 -4
  16. package/dist/application/JsonFiles.js +15 -15
  17. package/dist/application/LinuxHopper.js +2 -1
  18. package/dist/application/ReconstructionObligationCandidates.js +9 -2
  19. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  20. package/dist/application/RegularFileRead.js +17 -0
  21. package/dist/application/Setup.js +18 -7
  22. package/dist/application/SetupClientConfiguration.js +18 -7
  23. package/dist/application/SetupHost.js +6 -4
  24. package/dist/application/SetupPlan.js +19 -15
  25. package/dist/application/SetupSkill.js +57 -8
  26. package/dist/application/SupportedClients.js +43 -0
  27. package/dist/application/Uninstall.js +18 -2
  28. package/dist/application/UpdateMaintenance.js +6 -2
  29. package/dist/application/Utf8JsonInput.js +64 -0
  30. package/dist/application/WebScriptExportService.js +13 -6
  31. package/dist/application/android/AndroidAnalysisService.js +1 -1
  32. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  33. package/dist/application/binary/BinarySession.js +16 -0
  34. package/dist/application/binary/BinarySessionOpen.js +9 -1
  35. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  36. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  37. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  38. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  39. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  40. package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
  41. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  42. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
  43. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
  44. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
  45. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
  46. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
  47. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  48. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  49. package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
  50. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  51. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
  52. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  53. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  54. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  55. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
  56. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  57. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  58. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
  59. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
  60. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  61. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  62. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
  63. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  64. package/dist/application/native/NativeCallRoutes.js +2 -4
  65. package/dist/artifacts/ArtifactProvider.js +14 -16
  66. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  67. package/dist/artifacts/AsarArtifactReader.js +81 -17
  68. package/dist/artifacts/DirectoryArtifactReader.js +2 -2
  69. package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
  70. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  71. package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
  72. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  73. package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
  74. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
  75. package/dist/artifacts/inventory/classify.js +33 -14
  76. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  77. package/dist/artifacts/inventory/scanCanonical.js +28 -22
  78. package/dist/artifacts/inventory/scanReader.js +7 -11
  79. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  80. package/dist/browser/CdpBrowserProvider.js +4 -3
  81. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  82. package/dist/browser/CdpElectronInspection.js +2 -2
  83. package/dist/browser/CdpElectronProvider.js +4 -3
  84. package/dist/browser/CdpElectronScripts.js +2 -2
  85. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  86. package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
  87. package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
  88. package/dist/browser/PlaywrightScenarioSession.js +3 -11
  89. package/dist/browser/WebSourceMapFetcher.js +32 -6
  90. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  91. package/dist/cli/coreAnalysisCommands.js +2 -2
  92. package/dist/cli/coreBinaryCommands.js +13 -9
  93. package/dist/cli/electronCommands.js +9 -10
  94. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  95. package/dist/cli/jsonOutput.js +3 -2
  96. package/dist/cli/streamedJsonOutput.js +83 -4
  97. package/dist/cli/utilityCommands.js +2 -4
  98. package/dist/cli.js +5 -2
  99. package/dist/cliJsonFile.js +179 -0
  100. package/dist/cliJsonInput.js +47 -34
  101. package/dist/cliObservationOptions.js +4 -0
  102. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  103. package/dist/composition/browserScenario.js +2 -2
  104. package/dist/composition/directAnalysis.js +2 -3
  105. package/dist/contracts/artifactComparisonExample.js +5 -5
  106. package/dist/contracts/errorSchemas.js +3 -1
  107. package/dist/contracts/functionComparisonExample.js +8 -0
  108. package/dist/contracts/inputSchemaPresentation.js +94 -3
  109. package/dist/contracts/javascript/electronToolContracts.js +2 -1
  110. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  111. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  112. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  113. package/dist/contracts/managed/managedToolContracts.js +3 -2
  114. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  115. package/dist/contracts/native/nativeToolContracts.js +1 -1
  116. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  117. package/dist/contracts/sessionStatusContract.js +3 -2
  118. package/dist/contracts/sessionToolContracts.js +3 -2
  119. package/dist/contracts/sessionToolSchemas.js +3 -2
  120. package/dist/contracts/toolOutputSchemaGroups.js +2 -2
  121. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  122. package/dist/domain/analysisErrorBase.js +5 -0
  123. package/dist/domain/analysisErrorPresentation.js +4 -2
  124. package/dist/domain/analysisSnapshot.js +3 -1
  125. package/dist/domain/analysisView/analysisView.js +1 -3
  126. package/dist/domain/android/androidPartialObservation.js +36 -0
  127. package/dist/domain/apple/dylibResolution.js +1 -1
  128. package/dist/domain/artifactComparison.js +4 -4
  129. package/dist/domain/artifactGraph.js +1 -1
  130. package/dist/domain/artifactIdentity.js +8 -8
  131. package/dist/domain/artifactInspection.js +8 -8
  132. package/dist/domain/artifactInventoryEvidence.js +5 -5
  133. package/dist/domain/browserCompleteness.js +3 -2
  134. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  135. package/dist/domain/browserScenarioNormalization.js +3 -3
  136. package/dist/domain/browserScenarioValues.js +3 -2
  137. package/dist/domain/callPath.js +8 -10
  138. package/dist/domain/canonicalDigest.js +7 -1
  139. package/dist/domain/canonicalOrdering.js +1 -13
  140. package/dist/domain/changedBehavior.js +2 -3
  141. package/dist/domain/comparisonSemantics.js +0 -5
  142. package/dist/domain/digests.js +0 -3
  143. package/dist/domain/evidence.js +10 -5
  144. package/dist/domain/evidenceBundle.js +51 -33
  145. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  146. package/dist/domain/functionComparison.js +2 -1
  147. package/dist/domain/functionComparisonNormalization.js +4 -3
  148. package/dist/domain/functionComparisonResults.js +2 -2
  149. package/dist/domain/functionDossierEvidence.js +2 -1
  150. package/dist/domain/hopperValues.js +11 -15
  151. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  152. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
  153. package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
  154. package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
  155. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  156. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  157. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  158. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  159. package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
  160. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  161. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  162. package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
  163. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
  164. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  165. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  166. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  167. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  168. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  169. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  170. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  171. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  172. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  173. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  174. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
  175. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  176. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  177. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  178. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  179. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  180. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  181. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  182. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  183. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  184. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  185. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  186. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
  187. package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
  188. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  189. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  190. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  191. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  192. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  193. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  194. package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
  195. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  196. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  197. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  198. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
  199. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  200. package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
  201. package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
  202. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  203. package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
  204. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  205. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  206. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  207. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  208. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  209. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  210. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  211. package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
  212. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  213. package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
  214. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  215. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  216. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  217. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  218. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  219. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  220. package/dist/domain/jsonSerialization.js +109 -55
  221. package/dist/domain/jsonShape.js +46 -19
  222. package/dist/domain/localPath.js +10 -4
  223. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  224. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  225. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  226. package/dist/domain/native/nativeCallObservation.js +2 -4
  227. package/dist/domain/native/nativeValueFlow.js +5 -11
  228. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  229. package/dist/domain/process/processCapture.js +11 -10
  230. package/dist/domain/process/processCaptureCoverage.js +8 -5
  231. package/dist/domain/process/processCaptureExample.js +43 -0
  232. package/dist/domain/process/processCaptureValidation.js +4 -3
  233. package/dist/domain/process/processComparison.js +0 -23
  234. package/dist/domain/process/processScenario.js +3 -3
  235. package/dist/domain/process/processTraceEvaluation.js +4 -4
  236. package/dist/domain/process/processTraceSpecification.js +1 -3
  237. package/dist/domain/providerCleanupError.js +6 -2
  238. package/dist/domain/reconstructionCoverage.js +2 -1
  239. package/dist/domain/reconstructionUnknowns.js +4 -3
  240. package/dist/domain/reconstructionVerification.js +3 -2
  241. package/dist/domain/referenceSourceGraph.js +7 -7
  242. package/dist/domain/referenceSourceImportParsing.js +34 -45
  243. package/dist/domain/residualUnknown.js +3 -2
  244. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  245. package/dist/domain/swiftSymbolClassification.js +6 -1
  246. package/dist/domain/symbolAnalysis.js +17 -2
  247. package/dist/domain/unicodeCodePointOrder.js +6 -0
  248. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  249. package/dist/domain/webCaptureDiff.js +71 -29
  250. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  251. package/dist/domain/webInventory.js +3 -2
  252. package/dist/domain/webMcpDiscovery.js +4 -3
  253. package/dist/domain/webScriptExport.js +1 -1
  254. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  255. package/dist/dotnet/ManagedStaticProvider.js +10 -7
  256. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  257. package/dist/filesystem/RegularFile.js +41 -0
  258. package/dist/generatedPackageMetadata.js +1 -1
  259. package/dist/ghidra/GhidraClient.js +14 -4
  260. package/dist/ghidra/GhidraInstallation.js +111 -10
  261. package/dist/ghidra/GhidraLauncher.js +43 -19
  262. package/dist/hopper/HopperCleanup.js +1 -1
  263. package/dist/ida/IdaOperationRunner.js +2 -0
  264. package/dist/ida/IdaSessionClient.js +4 -2
  265. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  266. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  267. package/dist/inspector/V8InspectorProvider.js +60 -8
  268. package/dist/main/shutdown.js +76 -32
  269. package/dist/main/transport.js +1 -1
  270. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  271. package/dist/native/AppleObjcProperties.js +17 -7
  272. package/dist/native/LldbCallTracer.js +241 -75
  273. package/dist/native/NativeMacOSProvider.js +10 -5
  274. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  275. package/dist/process/ProcessOwnershipObservation.js +9 -13
  276. package/dist/process/capture/FilesystemSnapshot.js +88 -18
  277. package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
  278. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  279. package/dist/process/capture/ProcessHarness.js +8 -21
  280. package/dist/server/analysisAdmission.js +8 -0
  281. package/dist/server/createServer.js +22 -23
  282. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
  283. package/dist/server/registerApplicationTools/helpers.js +3 -2
  284. package/dist/server/registerArtifactTools.js +2 -2
  285. package/dist/server/registerCloseLifecycleTool.js +6 -4
  286. package/dist/server/registerEnhancedTools.js +78 -73
  287. package/dist/server/registerEvidenceTools.js +54 -46
  288. package/dist/server/registerManagedTools.js +7 -4
  289. package/dist/server/registerOfficialTools.js +31 -25
  290. package/dist/server/registerSessionTools.js +9 -3
  291. package/native/windows/build/manifest.json +1 -1
  292. package/package.json +6 -3
  293. package/skills/reverse-engineer-anything/SKILL.md +5 -5
  294. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  295. package/dist/artifacts/inventory/policy.js +0 -2
  296. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  297. package/dist/server/registerNativeTools.js +0 -6
@@ -13,6 +13,23 @@ const hasSameFileState = (before, after) => before.dev === after.dev &&
13
13
  before.size === after.size &&
14
14
  before.mtimeMs === after.mtimeMs &&
15
15
  before.ctimeMs === after.ctimeMs;
16
+ const fileUnavailableSystemCode = (cause) => {
17
+ if (!(cause instanceof Error) || !("code" in cause))
18
+ return undefined;
19
+ const code = cause.code;
20
+ return typeof code === "string" &&
21
+ [
22
+ "EACCES",
23
+ "EISDIR",
24
+ "ELOOP",
25
+ "ENOTDIR",
26
+ "ENOENT",
27
+ "EPERM",
28
+ "ESTALE",
29
+ ].includes(code)
30
+ ? code
31
+ : undefined;
32
+ };
16
33
  const lstatIfPresent = async (path) => {
17
34
  try {
18
35
  return await lstat(path);
@@ -26,15 +43,33 @@ const lstatIfPresent = async (path) => {
26
43
  /** Hash a file only when its opened descriptor still matches the captured path state. */
27
44
  export const hashFile = async (path, expected, maxBytes, signal) => {
28
45
  signal?.throwIfAborted();
29
- const handle = await open(path, fsConstants.O_RDONLY |
30
- (fsConstants.O_NOFOLLOW ?? 0) |
31
- (fsConstants.O_NONBLOCK ?? 0));
46
+ let handle;
47
+ try {
48
+ handle = await open(path, fsConstants.O_RDONLY |
49
+ (fsConstants.O_NOFOLLOW ?? 0) |
50
+ (fsConstants.O_NONBLOCK ?? 0));
51
+ }
52
+ catch (cause) {
53
+ signal?.throwIfAborted();
54
+ const systemCode = fileUnavailableSystemCode(cause);
55
+ if (systemCode === undefined)
56
+ throw cause;
57
+ return {
58
+ state: "omitted",
59
+ reason: "file_unavailable",
60
+ system_code: systemCode,
61
+ };
62
+ }
32
63
  try {
33
64
  signal?.throwIfAborted();
34
65
  const stats = await handle.stat();
35
66
  signal?.throwIfAborted();
36
67
  if (!hasSameFileState(expected, stats) || stats.size > maxBytes)
37
- return null;
68
+ return {
69
+ state: "omitted",
70
+ reason: "file_changed_or_short_read",
71
+ system_code: null,
72
+ };
38
73
  const hash = createHash("sha256");
39
74
  const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, maxBytes));
40
75
  let position = 0;
@@ -42,15 +77,34 @@ export const hashFile = async (path, expected, maxBytes, signal) => {
42
77
  signal?.throwIfAborted();
43
78
  const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, stats.size - position), position);
44
79
  if (bytesRead === 0)
45
- return null;
80
+ return {
81
+ state: "omitted",
82
+ reason: "file_changed_or_short_read",
83
+ system_code: null,
84
+ };
46
85
  hash.update(buffer.subarray(0, bytesRead));
47
86
  position += bytesRead;
48
87
  }
49
88
  const after = await handle.stat();
50
89
  signal?.throwIfAborted();
51
90
  if (!hasSameFileState(stats, after))
52
- return null;
53
- return hash.digest("hex");
91
+ return {
92
+ state: "omitted",
93
+ reason: "file_changed_or_short_read",
94
+ system_code: null,
95
+ };
96
+ return { state: "hashed", sha256: hash.digest("hex") };
97
+ }
98
+ catch (cause) {
99
+ signal?.throwIfAborted();
100
+ const systemCode = fileUnavailableSystemCode(cause);
101
+ if (systemCode === undefined)
102
+ throw cause;
103
+ return {
104
+ state: "omitted",
105
+ reason: "file_unavailable",
106
+ system_code: systemCode,
107
+ };
54
108
  }
55
109
  finally {
56
110
  await handle.close();
@@ -98,20 +152,36 @@ export const snapshotRoots = async (scenario, signal) => {
98
152
  return true;
99
153
  }
100
154
  if (stats.isFile()) {
101
- const sha256 = remainingBytes >= stats.size
102
- ? await hashFile(path, stats, remainingBytes, signal)
103
- : null;
104
- remainingBytes -= sha256 === null ? 0 : stats.size;
105
- if (sha256 === null) {
106
- truncated = true;
107
- hashOmissions.push({
155
+ let sha256 = null;
156
+ let omission;
157
+ if (remainingBytes < stats.size) {
158
+ omission = {
108
159
  path: `${rootAlias}:${relativePath}`,
109
160
  size_bytes: stats.size,
110
161
  remaining_budget_bytes: remainingBytes,
111
- reason: remainingBytes < stats.size
112
- ? "file_bytes_budget"
113
- : "file_changed_or_short_read",
114
- });
162
+ reason: "file_bytes_budget",
163
+ system_code: null,
164
+ };
165
+ }
166
+ else {
167
+ const outcome = await hashFile(path, stats, remainingBytes, signal);
168
+ if (outcome.state === "hashed") {
169
+ sha256 = outcome.sha256;
170
+ remainingBytes -= stats.size;
171
+ }
172
+ else {
173
+ omission = {
174
+ path: `${rootAlias}:${relativePath}`,
175
+ size_bytes: stats.size,
176
+ remaining_budget_bytes: remainingBytes,
177
+ reason: outcome.reason,
178
+ system_code: outcome.system_code,
179
+ };
180
+ }
181
+ }
182
+ if (omission !== undefined) {
183
+ truncated = true;
184
+ hashOmissions.push(omission);
115
185
  }
116
186
  entries.push({
117
187
  path: `${rootAlias}:${relativePath}`,
@@ -43,10 +43,7 @@ export const createProcessCaptureObservationBuffer = (options) => ({
43
43
  filesystem_snapshots: {
44
44
  before: {
45
45
  state: "available",
46
- value: {
47
- files: options.before.files,
48
- truncated: options.before.truncated,
49
- },
46
+ value: options.before,
50
47
  },
51
48
  after: {
52
49
  state: "unavailable",
@@ -97,8 +94,9 @@ export const buildCaptureResult = (options) => {
97
94
  const filesystemObservationUnknown = "No filesystem observation paths were selected; filesystem effects remain unknown.";
98
95
  const hasFilesystemObservations = options.scenario.filesystem_observation_paths.length > 0;
99
96
  const filesystemEffects = classifyFilesystemEffects(options.before, options.after);
100
- const hasUnknownFilesystemEffects = filesystemEffects.some(({ status }) => status === "unknown");
101
- const incompleteFilesystemUnknown = "Path absence in incomplete enumeration or below an unfollowed symbolic link remains unknown.";
97
+ const filesystemUnknowns = [
98
+ ...new Set(filesystemEffects.flatMap((effect) => effect.status === "unknown" ? [effect.reason] : [])),
99
+ ];
102
100
  return {
103
101
  manifest: options.manifest,
104
102
  normalization: options.scenario.normalization,
@@ -119,12 +117,8 @@ export const buildCaptureResult = (options) => {
119
117
  files_before: options.before.files,
120
118
  files_after: options.after.files,
121
119
  filesystem_effects: filesystemEffects,
122
- truncated: options.truncationDetails === undefined
123
- ? options.truncated
124
- : hasCaptureTruncation(options.truncationDetails),
125
- ...(options.truncationDetails === undefined
126
- ? {}
127
- : { truncation_details: options.truncationDetails }),
120
+ truncated: hasCaptureTruncation(options.truncationDetails),
121
+ truncation_details: options.truncationDetails,
128
122
  limitations: [
129
123
  "The executable digest is a prelaunch file sample; matching path metadata immediately after spawn does not prove an atomic operating-system image binding.",
130
124
  "Process trees are sampled and may omit short-lived descendants.",
@@ -134,10 +128,8 @@ export const buildCaptureResult = (options) => {
134
128
  "Filesystem observations are before/after snapshots, not syscall traces.",
135
129
  "Inherited host environment variables are not recorded and may affect results.",
136
130
  ...(!hasFilesystemObservations ? [filesystemObservationUnknown] : []),
137
- ...(hasUnknownFilesystemEffects ? [incompleteFilesystemUnknown] : []),
138
- ...(options.truncationDetails === undefined
139
- ? []
140
- : captureCoverageUnknowns(options.truncationDetails).map(({ reason }) => reason)),
131
+ ...filesystemUnknowns,
132
+ ...captureCoverageUnknowns(options.truncationDetails).map(({ reason }) => reason),
141
133
  ...(hasSensitiveScriptedInput ? [sensitiveInputUnknown] : []),
142
134
  ],
143
135
  residual_unknowns: [
@@ -165,20 +157,14 @@ export const buildCaptureResult = (options) => {
165
157
  },
166
158
  ]
167
159
  : []),
168
- ...(hasUnknownFilesystemEffects
169
- ? [
170
- {
171
- scope: "filesystem",
172
- reason: incompleteFilesystemUnknown,
173
- },
174
- ]
175
- : []),
160
+ ...filesystemUnknowns.map((reason) => ({
161
+ scope: "filesystem",
162
+ reason,
163
+ })),
176
164
  ...(hasSensitiveScriptedInput
177
165
  ? [{ scope: "interaction", reason: sensitiveInputUnknown }]
178
166
  : []),
179
- ...(options.truncationDetails === undefined
180
- ? []
181
- : captureCoverageUnknowns(options.truncationDetails).filter(({ scope }) => scope !== "terminal")),
167
+ ...captureCoverageUnknowns(options.truncationDetails).filter(({ scope }) => scope !== "terminal"),
182
168
  ],
183
169
  };
184
170
  };
@@ -13,7 +13,7 @@ const unobservedAbsenceReason = (path, phase, completeRoots, filesByPath) => {
13
13
  }
14
14
  return undefined;
15
15
  };
16
- /** Classify effects only when a snapshot establishes the missing path's absence. */
16
+ /** Classify effects only from observed path absence, metadata, and content hashes. */
17
17
  export const classifyFilesystemEffects = (before, after) => {
18
18
  const beforeByPath = new Map(before.files.map((file) => [file.path, file]));
19
19
  const afterByPath = new Map(after.files.map((file) => [file.path, file]));
@@ -54,11 +54,26 @@ export const classifyFilesystemEffects = (before, after) => {
54
54
  before: beforeFile,
55
55
  after: null,
56
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
+ };
57
72
  return {
58
73
  path,
59
- status: JSON.stringify(beforeFile) === JSON.stringify(afterFile)
60
- ? "unchanged"
61
- : "modified",
74
+ status: metadataChanged || beforeFile.sha256 !== afterFile.sha256
75
+ ? "modified"
76
+ : "unchanged",
62
77
  before: beforeFile,
63
78
  after: afterFile,
64
79
  };
@@ -220,7 +220,7 @@ const completeCapture = async (options) => {
220
220
  ...options.observationBuffer.filesystem_snapshots,
221
221
  after: {
222
222
  state: "available",
223
- value: { files: after.files, truncated: after.truncated },
223
+ value: after,
224
224
  },
225
225
  };
226
226
  options.recordEvent("filesystem_checkpoints", 1);
@@ -267,31 +267,19 @@ const completeCapture = async (options) => {
267
267
  throw cause;
268
268
  }
269
269
  options.observationBuffer.manifest = { state: "available", value: manifest };
270
- const truncated = options.initiallyTruncated ||
271
- after.truncated ||
272
- runtime.rawTerminalRetention().observed_frames >
273
- runtime.rawTerminalRetention().retained_frames ||
274
- checkpoints.some(({ truncated: partial }) => partial) ||
275
- samplingPartial ||
276
- runtime.renderer.truncated();
277
270
  return buildCaptureResult({
278
271
  frames: options.frames,
279
272
  exit: { ...options.exit, reason },
280
273
  samples: options.samples,
281
274
  before: options.before,
282
275
  after,
283
- truncated,
284
- ...(options.before.coverage === undefined || after.coverage === undefined
285
- ? {}
286
- : {
287
- truncationDetails: {
288
- raw_terminal: runtime.rawTerminalRetention(),
289
- rendered_terminal: runtime.renderer.retention(),
290
- filesystem_before: options.before.coverage,
291
- filesystem_after: after.coverage,
292
- process: sampling.coverage,
293
- },
294
- }),
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
+ },
295
283
  scenario,
296
284
  rootPid: runtime.terminal.pid,
297
285
  samplingPartial,
@@ -377,7 +365,6 @@ const runProcessScenario = async (scenario, signal, hostEnvironment = process.en
377
365
  samples,
378
366
  interactions,
379
367
  exit,
380
- initiallyTruncated: before.truncated,
381
368
  eventJournal,
382
369
  observationBuffer: observations,
383
370
  recordEvent,
@@ -0,0 +1,8 @@
1
+ import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
2
+ import { err, ok } from "../domain/result.js";
3
+ /** Run against the source's explicit owner, admitting session-scoped work. */
4
+ export const withAdmittedAnalysis = (source) => source.kind === "session"
5
+ ? (operationName, signal, operation) => source.session.withAdmittedAnalysis(operationName, signal, operation)
6
+ : async (operationName, signal, operation) => signal?.aborted === true
7
+ ? err(new AnalysisCancelledError(operationName))
8
+ : ok(await operation(source.analysis));
@@ -39,11 +39,13 @@ import { registerAndroidTools } from "./registerAndroidTools.js";
39
39
  import { AndroidAnalysisService } from "../application/android/AndroidAnalysisService.js";
40
40
  import { createAndroidAnalysisProvider } from "../composition/android.js";
41
41
  import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
42
- import { registerNativeTools } from "./registerNativeTools.js";
42
+ import { NATIVE_TOOL_CONTRACTS } from "../contracts/native/nativeToolContracts.js";
43
+ import { registerEvidenceTools } from "./registerEvidenceTools.js";
43
44
  import { registerOfficialTools } from "./registerOfficialTools.js";
44
45
  import { registerGuidedPrompts } from "./registerPrompts.js";
45
46
  import { registerSessionTools } from "./registerSessionTools.js";
46
47
  import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
48
+ import { withAdmittedAnalysis, } from "./analysisAdmission.js";
47
49
  const TARGET_FREE_INSTRUCTIONS = "REA provides reverse-engineering tools for local artifacts, native binaries, managed code, browser pages, and runtimes. Use the tool that directly answers the question; discover targets or inspect inventory only when needed. Tool results include inline Evidence and report their coverage and limitations.";
48
50
  const ACTIVE_TARGET_INSTRUCTIONS = "REA analyzes the active reverse-engineering target. Use the analysis tool that answers the question directly. Search or list symbols when discovery is needed; analyze_function provides a function dossier, and focused procedure tools return individual facets.";
49
51
  const installSessionToolAvailability = (session, options, environment) => {
@@ -93,7 +95,9 @@ const createMcpServer = (session, delivery) => new EvidenceMcpServer({
93
95
  * Supplying a session adds target lifecycle tools; omitting it retains the
94
96
  * fixed-target seam used by focused tests and embedders.
95
97
  */
96
- export const createServer = (analysis, session, options = {}) => {
98
+ export const createServer = (source, options = {}) => {
99
+ const session = source.kind === "session" ? source.session : undefined;
100
+ const analysis = source.kind === "session" ? source.session : source.analysis;
97
101
  const environment = snapshotEnvironment(options.environment ?? process.env);
98
102
  const delivery = selectToolResultDelivery(environment, options.delivery);
99
103
  const selectedOptions = { ...options, environment, delivery };
@@ -106,7 +110,6 @@ export const createServer = (analysis, session, options = {}) => {
106
110
  const { evidenceById, activeTarget, recordEvidence, recordEvidenceWithUnknown, } = createSessionRecorders(server, session);
107
111
  const toolContext = {
108
112
  server,
109
- analysis,
110
113
  session,
111
114
  options: selectedOptions,
112
115
  environment,
@@ -115,6 +118,7 @@ export const createServer = (analysis, session, options = {}) => {
115
118
  activeTarget,
116
119
  recordEvidence,
117
120
  recordEvidenceWithUnknown,
121
+ withAdmittedAnalysis: withAdmittedAnalysis(source),
118
122
  };
119
123
  registerBinaryAnalysisTools(toolContext);
120
124
  const previousOnclose = server.server.onclose;
@@ -176,18 +180,12 @@ const createSessionRecorders = (server, session) => ({
176
180
  activeTarget: session === undefined ? undefined : () => session.activeTarget(),
177
181
  recordEvidence: session === undefined
178
182
  ? undefined
179
- : (evidence) => {
180
- const recorded = session.recordEvidence(evidence);
181
- return recorded;
182
- },
183
+ : (evidence) => session.recordEvidence(evidence),
183
184
  recordEvidenceWithUnknown: session === undefined
184
185
  ? undefined
185
- : (evidence, input) => {
186
- const recorded = session.recordEvidenceWithUnknown(evidence, input);
187
- return recorded;
188
- },
186
+ : (evidence, input) => session.recordEvidenceWithUnknown(evidence, input),
189
187
  });
190
- const registerBinaryAnalysisTools = ({ server, analysis, session, logger, activeTarget, recordEvidence, recordEvidenceWithUnknown, }) => {
188
+ const registerBinaryAnalysisTools = ({ server, session, logger, activeTarget, recordEvidence, recordEvidenceWithUnknown, withAdmittedAnalysis, }) => {
191
189
  const recordUnknown = session === undefined
192
190
  ? undefined
193
191
  : (input) => session.recordUnknown(input);
@@ -196,9 +194,10 @@ const registerBinaryAnalysisTools = ({ server, analysis, session, logger, active
196
194
  activeTarget,
197
195
  recordEvidence,
198
196
  recordUnknown,
197
+ withAdmittedAnalysis,
199
198
  };
200
- registerOfficialTools(server, analysis, analysisOptions);
201
- registerEnhancedTools(server, analysis, {
199
+ registerOfficialTools(server, analysisOptions);
200
+ registerEnhancedTools(server, {
202
201
  ...analysisOptions,
203
202
  analysisProfile: session === undefined ? undefined : () => session.analysisProfile(),
204
203
  allowsSnapshotReplay: session === undefined
@@ -208,15 +207,15 @@ const registerBinaryAnalysisTools = ({ server, analysis, session, logger, active
208
207
  ? undefined
209
208
  : (input) => session.recordWorkflowSnapshot(input),
210
209
  });
211
- const evidenceOptions = { logger, activeTarget, recordEvidence };
212
- registerNativeTools(server, analysis, evidenceOptions);
213
- registerArtifactTools(server, analysis, {
214
- ...evidenceOptions,
215
- });
216
- registerManagedTools(server, analysis, {
217
- ...evidenceOptions,
218
- session,
219
- });
210
+ const evidenceOptions = {
211
+ logger,
212
+ activeTarget,
213
+ recordEvidence,
214
+ withAdmittedAnalysis,
215
+ };
216
+ registerEvidenceTools(server, NATIVE_TOOL_CONTRACTS, evidenceOptions);
217
+ registerArtifactTools(server, evidenceOptions);
218
+ registerManagedTools(server, evidenceOptions);
220
219
  if (session !== undefined)
221
220
  registerManagedWorkflowTools(server, {
222
221
  logger,
@@ -24,7 +24,8 @@ export const registerCompareJavaScriptExportShapesTool = (server, options) => {
24
24
  if (!recorded.ok)
25
25
  return server.delivery.toCallToolResult(recorded, contract);
26
26
  const comparison = javaScriptExportShapeComparisonResultSchema.parse(result.value.normalized_result);
27
- const unknown = comparison.summary.unknown > 0;
27
+ const unknown = comparison.summary.unknown > 0 ||
28
+ comparison.coverage.status !== "complete-within-inputs";
28
29
  return recordResult({ ...options, delivery: server.delivery }, contract, result.value, unknown ? "javascript-export-shape" : undefined);
29
30
  });
30
31
  };
@@ -6,11 +6,12 @@ export const recordResult = (options, contract, evidence, unknownKind) => {
6
6
  return options.delivery.toEvidenceToolResult(evidence, contract, recorded);
7
7
  };
8
8
  const unknownRegistration = (evidence, kind) => ({
9
- question: kind === "application-version-comparison"
9
+ // Scope unknown identity to the comparison while keeping exact replays stable.
10
+ question: `${kind === "application-version-comparison"
10
11
  ? "Which application entities remain unmatched or ambiguous across these versions?"
11
12
  : kind === "source-to-bundle-comparison"
12
13
  ? "Which historical source files remain unmatched or ambiguously mapped to the shipped bundle?"
13
- : "Which selected JavaScript export return shapes remain dynamic, incomplete, or ambiguously paired?",
14
+ : "Which selected JavaScript export return shapes remain dynamic, incomplete, or ambiguously paired?"} (comparison ${evidence.evidence_id})`,
14
15
  severity: "medium",
15
16
  domain: kind,
16
17
  supporting_evidence_ids: [evidence.evidence_id],
@@ -2,8 +2,8 @@ import { ARTIFACT_TOOL_CONTRACTS } from "../contracts/artifactToolContracts.js";
2
2
  import { registerEvidenceTools } from "./registerEvidenceTools.js";
3
3
  import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
4
4
  /** Register deterministic artifact inventory and safe extraction operations. */
5
- export const registerArtifactTools = (server, analysis, options) => {
6
- registerEvidenceTools(server, analysis, ARTIFACT_TOOL_CONTRACTS, {
5
+ export const registerArtifactTools = (server, options) => {
6
+ registerEvidenceTools(server, ARTIFACT_TOOL_CONTRACTS, {
7
7
  ...options,
8
8
  sourceEvidence: (operation, result) => operation === "inspect_artifact"
9
9
  ? artifactInspectionResultSchema
@@ -9,15 +9,17 @@ export const registerCloseLifecycleTool = ({ server, session, logger, closeContr
9
9
  const progress = mcpProgressReporter(context);
10
10
  const snapshotPath = input.snapshot_path;
11
11
  if (snapshotPath === undefined) {
12
+ // Enqueue the lifecycle transition before awaiting progress transport so
13
+ // a later open request cannot overtake this close.
14
+ const closing = logToolExecution(logger, closeContract.name, () => session.close({ progress }));
12
15
  await reportLifecycleStart(progress, closeContract.name);
13
- const closed = await logToolExecution(logger, closeContract.name, () => session.close({ progress }));
16
+ const closed = await closing;
14
17
  await reportLifecycleEnd(progress, closeContract.name, closed.ok);
15
18
  return server.delivery.toCallToolResult(closed, closeContract);
16
19
  }
20
+ const closing = logToolExecution(logger, closeContract.name, () => session.closeWithSnapshot(snapshotPath, input.overwrite, { progress }));
17
21
  await reportLifecycleStart(progress, closeContract.name, "saving snapshot; closing provider");
18
- const closed = await logToolExecution(logger, closeContract.name, () => session.closeWithSnapshot(snapshotPath, input.overwrite, {
19
- progress,
20
- }));
22
+ const closed = await closing;
21
23
  await reportLifecycleEnd(progress, closeContract.name, closed.ok);
22
24
  return server.delivery.toCallToolResult(closed.ok ? ok({ ...closed.value }) : closed, closeContract);
23
25
  });