rea-agents 1.7.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/README.md +112 -59
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +42 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +11 -29
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +165 -197
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +112 -0
  26. package/dist/application/ElectronBoundaryGraph.js +9 -0
  27. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  28. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  29. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  30. package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
  31. package/dist/application/EnhancedToolPagination.js +22 -0
  32. package/dist/application/EnhancedToolTypes.js +4 -0
  33. package/dist/application/EnhancedTools.js +58 -50
  34. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  35. package/dist/application/InvestigationProviders.js +30 -0
  36. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  37. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  38. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  39. package/dist/application/JavaScriptApplicationService.js +74 -0
  40. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  41. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  42. package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
  43. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  44. package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
  45. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  46. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  47. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  48. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  49. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  50. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  51. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  52. package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
  53. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  54. package/dist/application/JavaScriptJsonModules.js +39 -0
  55. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  56. package/dist/application/JavaScriptReplayPermission.js +16 -0
  57. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  58. package/dist/application/JavaScriptReplayService.js +292 -0
  59. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  60. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  61. package/dist/application/LinuxHopper.js +10 -0
  62. package/dist/application/MacHopper.js +22 -11
  63. package/dist/application/ManagedApplicationGraphService.js +55 -0
  64. package/dist/application/ManagedMemberComparisonService.js +122 -0
  65. package/dist/application/ManagedNativeVerificationService.js +39 -0
  66. package/dist/application/ManagedReconstructionService.js +58 -0
  67. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  68. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  69. package/dist/application/PermissionAuthority.js +106 -63
  70. package/dist/application/ProcessCaptureCapability.js +1 -1
  71. package/dist/application/ProcessCapturePermission.js +13 -0
  72. package/dist/application/ProcessCli.js +2 -12
  73. package/dist/application/ProcessHarness.js +1 -1
  74. package/dist/application/ProcessSampling.js +15 -11
  75. package/dist/application/ProjectPermissionStore.js +49 -9
  76. package/dist/application/RealHopperAssertions.js +76 -0
  77. package/dist/application/ReconstructionCoverageService.js +69 -0
  78. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  79. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  80. package/dist/application/Setup.js +147 -259
  81. package/dist/application/SetupClientConfiguration.js +220 -0
  82. package/dist/application/SetupClients.js +24 -2
  83. package/dist/application/SetupPlan.js +123 -12
  84. package/dist/application/SetupSkill.js +26 -12
  85. package/dist/application/SupportedClients.js +1 -0
  86. package/dist/application/Uninstall.js +6 -3
  87. package/dist/application/WindowsCapabilities.js +86 -0
  88. package/dist/application/runtime.js +2 -0
  89. package/dist/artifacts/AsarArtifactReader.js +11 -0
  90. package/dist/browser/BrowserProcessStartup.js +88 -0
  91. package/dist/browser/CdpCaptureDocuments.js +12 -8
  92. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  93. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  94. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  95. package/dist/browser/CdpCaptureEventState.js +1 -0
  96. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  97. package/dist/browser/CdpCaptureEvents.js +46 -464
  98. package/dist/browser/CdpElectronInspection.js +106 -162
  99. package/dist/browser/CdpElectronProvider.js +5 -1
  100. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  101. package/dist/browser/CdpElectronScripts.js +94 -0
  102. package/dist/browser/CdpElectronWorkers.js +56 -0
  103. package/dist/browser/CdpObservationSession.js +51 -8
  104. package/dist/browser/CdpPageCapture.js +12 -129
  105. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  106. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  107. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  108. package/dist/browser/PngVisualDiff.js +9 -2
  109. package/dist/catalogIdentity.js +8 -1
  110. package/dist/cli/artifactCommands.js +82 -0
  111. package/dist/cli/coreAnalysisCommands.js +232 -0
  112. package/dist/cli/managedCommands.js +397 -0
  113. package/dist/cli/managedProjectGraphCommand.js +24 -0
  114. package/dist/cli/options.js +9 -0
  115. package/dist/cli/setupCommands.js +108 -0
  116. package/dist/cli/types.js +1 -0
  117. package/dist/cli/utilityCommands.js +122 -0
  118. package/dist/cli.js +13 -383
  119. package/dist/cliApplicationCommands.js +176 -0
  120. package/dist/cliBrowserAdvancedCommands.js +73 -16
  121. package/dist/cliBrowserCommands.js +39 -115
  122. package/dist/cliCommandNames.js +17 -0
  123. package/dist/cliElectronCommands.js +100 -27
  124. package/dist/cliEvidenceCommands.js +13 -2
  125. package/dist/cliInvestigationCommands.js +53 -10
  126. package/dist/cliJsonInput.js +54 -0
  127. package/dist/cliObservationOptions.js +137 -0
  128. package/dist/cliPolicyCommands.js +80 -46
  129. package/dist/cliSetup.js +289 -0
  130. package/dist/config/environment.js +107 -0
  131. package/dist/config/parseConfig.js +228 -0
  132. package/dist/config/parsers.js +68 -0
  133. package/dist/config/permissions.js +30 -0
  134. package/dist/config/types.js +1 -0
  135. package/dist/config.js +1 -292
  136. package/dist/contracts/applicationToolContracts.js +225 -0
  137. package/dist/contracts/artifactToolContracts.js +5 -9
  138. package/dist/contracts/browserToolContracts.js +14 -62
  139. package/dist/contracts/electronToolContracts.js +45 -19
  140. package/dist/contracts/errorSchemas.js +1 -0
  141. package/dist/contracts/investigationExamples.js +0 -6
  142. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  143. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  144. package/dist/contracts/managedToolContracts.js +153 -0
  145. package/dist/contracts/managedWorkflowExamples.js +346 -0
  146. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  147. package/dist/contracts/nativeToolContracts.js +2 -6
  148. package/dist/contracts/promptContracts.js +18 -2
  149. package/dist/contracts/providerSelection.js +2 -0
  150. package/dist/contracts/toolContractExamples.js +10 -25
  151. package/dist/contracts/toolContracts.js +49 -47
  152. package/dist/contracts/toolEffects.js +174 -0
  153. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  154. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  155. package/dist/contracts/toolOutputSchemas.js +2 -535
  156. package/dist/doctorRuntime.js +42 -1
  157. package/dist/domain/analysisErrorPresentation.js +234 -0
  158. package/dist/domain/analysisErrorProjection.js +284 -0
  159. package/dist/domain/artifactComparison.js +37 -19
  160. package/dist/domain/binaryTarget.js +87 -37
  161. package/dist/domain/browserObservation.js +1 -282
  162. package/dist/domain/browserObservationSchemas.js +286 -0
  163. package/dist/domain/bundleComparison.js +4 -4
  164. package/dist/domain/electronObservation.js +13 -0
  165. package/dist/domain/electronStaticAnalysis.js +9 -0
  166. package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
  167. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  168. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  169. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  170. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  171. package/dist/domain/errors.js +32 -448
  172. package/dist/domain/functionComparison.js +4 -165
  173. package/dist/domain/functionComparisonDimensions.js +164 -0
  174. package/dist/domain/functionComparisonSchemas.js +3 -8
  175. package/dist/domain/inputIssueProjection.js +52 -0
  176. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  177. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  178. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  179. package/dist/domain/javascriptApplicationGraph.js +2 -1
  180. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  181. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  182. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  183. package/dist/domain/javascriptApplicationVersionItems.js +233 -0
  184. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  185. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  186. package/dist/domain/javascriptFeatureSeed.js +140 -0
  187. package/dist/domain/javascriptFeatureTrace.js +232 -0
  188. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  189. package/dist/domain/javascriptFeatureTraversal.js +100 -0
  190. package/dist/domain/javascriptNativeHandoff.js +85 -0
  191. package/dist/domain/javascriptReplay.js +361 -0
  192. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  193. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  194. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  195. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  196. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  197. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  198. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  199. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  200. package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
  201. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  202. package/dist/domain/javascriptSemanticIr.js +30 -0
  203. package/dist/domain/javascriptSemanticProjection.js +366 -0
  204. package/dist/domain/javascriptSemanticState.js +40 -0
  205. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  206. package/dist/domain/javascriptSemanticValues.js +352 -0
  207. package/dist/domain/javascriptStaticAnalysis.js +26 -254
  208. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  209. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  210. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  211. package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
  212. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  213. package/dist/domain/knownPageCoverage.js +21 -0
  214. package/dist/domain/managedApplicationGraph.js +206 -0
  215. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  216. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  217. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  218. package/dist/domain/managedArtifact.js +452 -0
  219. package/dist/domain/managedMemberComparison.js +211 -0
  220. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  221. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  222. package/dist/domain/managedNativeVerification.js +46 -0
  223. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  224. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  225. package/dist/domain/managedReconstruction.js +196 -0
  226. package/dist/domain/managedRuntimeCorrelation.js +184 -0
  227. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  228. package/dist/domain/permissionPolicy.js +2 -0
  229. package/dist/domain/reconstructionCoverage.js +387 -0
  230. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  231. package/dist/domain/reconstructionVerificationSchemas.js +9 -3
  232. package/dist/domain/runtimeCharacterization.js +85 -0
  233. package/dist/domain/webBundleAnalyzer.js +3 -409
  234. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  235. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  236. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  237. package/dist/dotnet/ManagedArtifactInspector.js +339 -0
  238. package/dist/dotnet/ManagedMemberInspector.js +153 -0
  239. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  240. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  241. package/dist/dotnet/ManagedMemberRows.js +120 -0
  242. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  243. package/dist/dotnet/ManagedMetadataInventory.js +104 -0
  244. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  245. package/dist/dotnet/ManagedMetadataLayout.js +259 -0
  246. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  247. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  248. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  249. package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
  250. package/dist/dotnet/ManagedPeReader.js +188 -0
  251. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  252. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  253. package/dist/generatedPackageMetadata.js +2 -2
  254. package/dist/ghidra/GhidraClient.js +76 -91
  255. package/dist/ghidra/GhidraClientStartup.js +29 -0
  256. package/dist/ghidra/GhidraClientWire.js +34 -0
  257. package/dist/ghidra/GhidraDefaults.js +1 -1
  258. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  259. package/dist/ghidra/GhidraInstallation.js +20 -15
  260. package/dist/ghidra/GhidraLauncher.js +93 -29
  261. package/dist/ghidra/GhidraProvider.js +67 -161
  262. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  263. package/dist/ghidra/GhidraSessionValues.js +2 -0
  264. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  265. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  266. package/dist/ghidra/GhidraTransport.js +71 -0
  267. package/dist/identity.js +3 -2
  268. package/dist/main/messages.js +5 -0
  269. package/dist/main/reload.js +49 -0
  270. package/dist/main/shutdown.js +25 -0
  271. package/dist/main/startup.js +14 -0
  272. package/dist/main/state.js +26 -0
  273. package/dist/main/transport.js +61 -0
  274. package/dist/main/types.js +1 -0
  275. package/dist/main.js +35 -132
  276. package/dist/process/PrivateRuntimeRoot.js +3 -2
  277. package/dist/process/ProcessOwnership.js +35 -0
  278. package/dist/process/ProviderProcess.js +2 -0
  279. package/dist/replay/JavaScriptReplayWorker.js +300 -0
  280. package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
  281. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  282. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  283. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  284. package/dist/replay/ReplayOutcome.js +95 -0
  285. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  286. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  287. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  288. package/dist/server/ProcessCaptureElicitation.js +157 -0
  289. package/dist/server/createServer.js +158 -41
  290. package/dist/server/registerApplicationTools/characterization.js +57 -0
  291. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  292. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  293. package/dist/server/registerApplicationTools/coverage.js +84 -0
  294. package/dist/server/registerApplicationTools/helpers.js +42 -0
  295. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  296. package/dist/server/registerApplicationTools/types.js +1 -0
  297. package/dist/server/registerApplicationTools.js +13 -0
  298. package/dist/server/registerArtifactComparisonTool.js +16 -9
  299. package/dist/server/registerBrowserTools.js +61 -60
  300. package/dist/server/registerBundleComparisonTool.js +17 -20
  301. package/dist/server/registerElectronTools.js +39 -12
  302. package/dist/server/registerEnhancedTools.js +52 -15
  303. package/dist/server/registerEvidenceResources.js +54 -0
  304. package/dist/server/registerEvidenceTools.js +5 -1
  305. package/dist/server/registerFunctionComparisonTool.js +14 -7
  306. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  307. package/dist/server/registerInvestigationTools/types.js +1 -0
  308. package/dist/server/registerInvestigationTools.js +103 -132
  309. package/dist/server/registerManagedTools.js +6 -0
  310. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  311. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  312. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  313. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  314. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  315. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  316. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  317. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  318. package/dist/server/registerManagedWorkflowTools.js +13 -0
  319. package/dist/server/registerOfficialTools.js +81 -67
  320. package/dist/server/registerProcessComparisonTool.js +25 -47
  321. package/dist/server/registerSessionRecordTools.js +137 -0
  322. package/dist/server/registerSessionStatusTool.js +9 -8
  323. package/dist/server/registerSessionTools.js +77 -216
  324. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  325. package/dist/server/sessionEvidence.js +14 -19
  326. package/dist/server/toolInputValidation.js +77 -0
  327. package/dist/server/toolRegistrationOptions.js +177 -2
  328. package/dist/server/toolResult.js +30 -17
  329. package/package.json +21 -14
  330. package/scripts/rea.mjs +1 -1
  331. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
  332. package/scripts/prepare-node-pty.mjs +0 -35
  333. package/scripts/rebuild-native.mjs +0 -22
@@ -0,0 +1,272 @@
1
+ import { createHash } from "node:crypto";
2
+ import { basename } from "node:path";
3
+ import canonicalize from "canonicalize";
4
+ import { parseEvidence } from "./evidence.js";
5
+ import { functionDossierSchema } from "./hopperValues.js";
6
+ import { inspectMachoSchema } from "./nativeInspection.js";
7
+ import { pinvokeVerificationSchema, } from "./managedNativeVerificationSchemas.js";
8
+ const digest = (value) => {
9
+ const serialized = canonicalize(value);
10
+ if (serialized === undefined)
11
+ throw new TypeError("Managed/native verification canonicalization failed");
12
+ return createHash("sha256").update(serialized).digest("hex");
13
+ };
14
+ const moduleName = (evidence) => evidence.subject?.name ?? null;
15
+ const modulePath = (evidence) => evidence.subject?.local_path ?? null;
16
+ const symbolsForEvidence = (evidence) => {
17
+ if (evidence.operation === "inspect_macho") {
18
+ const result = inspectMachoSchema.parse(evidence.normalized_result);
19
+ return {
20
+ supported: true,
21
+ symbols: result.exports.items.map((symbol) => ({
22
+ evidence_id: evidence.evidence_id,
23
+ operation: evidence.operation,
24
+ name: symbol.name,
25
+ address: symbol.address,
26
+ module_name: moduleName(evidence),
27
+ module_path: modulePath(evidence),
28
+ source: "macho-export",
29
+ })),
30
+ };
31
+ }
32
+ if (evidence.operation === "analyze_function") {
33
+ const dossier = functionDossierSchema.parse(evidence.normalized_result);
34
+ return {
35
+ supported: true,
36
+ symbols: [
37
+ {
38
+ evidence_id: evidence.evidence_id,
39
+ operation: evidence.operation,
40
+ name: dossier.procedure.name,
41
+ address: dossier.procedure.address,
42
+ module_name: moduleName(evidence),
43
+ module_path: modulePath(evidence),
44
+ source: "function-dossier",
45
+ },
46
+ ],
47
+ };
48
+ }
49
+ return { supported: false, symbols: [] };
50
+ };
51
+ export const collectNativeSymbols = (observations) => {
52
+ const symbols = [];
53
+ let accepted = 0;
54
+ let unsupported = 0;
55
+ for (const raw of observations) {
56
+ const evidence = parseEvidence(raw);
57
+ const extracted = symbolsForEvidence(evidence);
58
+ if (!extracted.supported) {
59
+ unsupported += 1;
60
+ }
61
+ else {
62
+ accepted += 1;
63
+ symbols.push(...extracted.symbols);
64
+ }
65
+ }
66
+ return { symbols, accepted, unsupported };
67
+ };
68
+ const normalizeSymbol = (value) => value.replace(/^_+/u, "").replace(/@\d+$/u, "").toLowerCase();
69
+ const sameSymbolName = (left, right) => normalizeSymbol(left) === normalizeSymbol(right);
70
+ const normalizeModule = (value) => basename(value)
71
+ .toLowerCase()
72
+ .replace(/^lib/u, "")
73
+ .replace(/\.(dll|dylib|so|node|exe)$/u, "");
74
+ const moduleCompatible = (scope, symbol) => {
75
+ if (scope === null)
76
+ return true;
77
+ const expected = normalizeModule(scope);
78
+ return [symbol.module_name, symbol.module_path]
79
+ .filter((value) => value !== null)
80
+ .map(normalizeModule)
81
+ .some((value) => value === expected);
82
+ };
83
+ const candidateNames = (managed) => {
84
+ const names = new Set([managed.import_name]);
85
+ if (!managed.no_mangle) {
86
+ if (managed.char_set === "unicode")
87
+ names.add(`${managed.import_name}W`);
88
+ if (managed.char_set === "ansi")
89
+ names.add(`${managed.import_name}A`);
90
+ if (managed.call_convention === "stdcall") {
91
+ names.add(`_${managed.import_name}`);
92
+ names.add(`_${managed.import_name}@0`);
93
+ }
94
+ }
95
+ return [...names];
96
+ };
97
+ const selectCandidates = (managed, symbols, maxCandidates) => {
98
+ const names = candidateNames(managed);
99
+ const allCandidates = symbols.filter((symbol) => names.some((name) => sameSymbolName(name, symbol.name)));
100
+ const candidates = allCandidates.slice(0, maxCandidates);
101
+ const exact = candidates.find((symbol) => sameSymbolName(managed.import_name, symbol.name) &&
102
+ moduleCompatible(managed.import_scope_name, symbol));
103
+ const decorated = candidates.find((symbol) => moduleCompatible(managed.import_scope_name, symbol));
104
+ const selected = exact ?? decorated ?? candidates[0] ?? null;
105
+ return { allCandidates, candidates, selected, exact, decorated };
106
+ };
107
+ const basisAndStatus = (managed, selection, hasSupportedNativeEvidence) => {
108
+ const { selected, exact } = selection;
109
+ if (selected === null)
110
+ return {
111
+ basis: hasSupportedNativeEvidence
112
+ ? "no-native-candidate"
113
+ : "unsupported-native-evidence",
114
+ status: "unresolved",
115
+ confidence: "unknown",
116
+ };
117
+ if (!moduleCompatible(managed.import_scope_name, selected))
118
+ return {
119
+ basis: "module-mismatch",
120
+ status: "contradicted",
121
+ confidence: "unknown",
122
+ };
123
+ if (exact !== undefined)
124
+ return {
125
+ basis: selected.source === "macho-export"
126
+ ? "exact-export-name"
127
+ : "exact-function-name",
128
+ status: "verified",
129
+ confidence: "observed",
130
+ };
131
+ return {
132
+ basis: "decorated-name-candidate",
133
+ status: "inferred",
134
+ confidence: "inferred",
135
+ };
136
+ };
137
+ const pinvokeLimitations = (status, managed) => [
138
+ ...(managed.import_scope_name === null
139
+ ? ["Managed declaration does not name an import scope/module."]
140
+ : []),
141
+ ...(status === "inferred"
142
+ ? [
143
+ "Native symbol matched a decorated candidate rather than the exact declared import name.",
144
+ ]
145
+ : []),
146
+ ...(status === "contradicted"
147
+ ? [
148
+ "A symbol name candidate exists, but the supplied native Evidence module identity does not match the managed import scope.",
149
+ ]
150
+ : []),
151
+ ...(status === "unresolved"
152
+ ? [
153
+ "No supplied native export/function Evidence matched this declared import.",
154
+ ]
155
+ : []),
156
+ ];
157
+ export const verifyPinvoke = ({ item, managedEvidenceId, symbols, hasSupportedNativeEvidence, input, }) => {
158
+ const managed = {
159
+ token: item.token,
160
+ member_token: item.member_token,
161
+ member_name: item.member_name,
162
+ import_name: item.import_name,
163
+ import_scope_name: item.import_scope_name,
164
+ no_mangle: item.no_mangle,
165
+ char_set: item.char_set,
166
+ call_convention: item.call_convention,
167
+ declaration_verification: item.verification,
168
+ };
169
+ const selection = selectCandidates(item, symbols, input.limits.max_candidates_per_import);
170
+ const { status, basis, confidence } = basisAndStatus(item, selection, hasSupportedNativeEvidence);
171
+ const limitations = pinvokeLimitations(status, item);
172
+ return {
173
+ verification: pinvokeVerificationSchema.parse({
174
+ item_id: `mnv_pinvoke_${digest({
175
+ managedEvidenceId,
176
+ token: item.token,
177
+ importName: item.import_name,
178
+ importScope: item.import_scope_name,
179
+ candidates: [...selection.candidates],
180
+ })}`,
181
+ managed,
182
+ status,
183
+ basis,
184
+ confidence,
185
+ matched_native: selection.selected,
186
+ candidates: selection.candidates,
187
+ evidence_links: [
188
+ managedEvidenceId,
189
+ ...new Set(selection.candidates.map(({ evidence_id: id }) => id)),
190
+ ],
191
+ limitations,
192
+ }),
193
+ omittedCandidates: Math.max(0, selection.allCandidates.length - selection.candidates.length),
194
+ };
195
+ };
196
+ const countStatuses = (items) => ({
197
+ verified: items.filter(({ status }) => status === "verified").length,
198
+ inferred: items.filter(({ status }) => status === "inferred").length,
199
+ unresolved: items.filter(({ status }) => status === "unresolved").length,
200
+ contradicted: items.filter(({ status }) => status === "contradicted").length,
201
+ });
202
+ export const buildVerificationResult = ({ managedEvidence, managed, native, pinvokeImports, verifiedPinvokes, input, }) => {
203
+ const counts = countStatuses(pinvokeImports);
204
+ const omittedNativeObservations = Math.max(0, input.native_observations.length - input.limits.max_native_observations);
205
+ const omittedCandidates = verifiedPinvokes.reduce((sum, item) => sum + item.omittedCandidates, 0);
206
+ const nativeBodyUnresolved = managed.native_implementations.items.filter(({ boundary_kind: kind }) => kind !== "pinvoke").length;
207
+ const coverageStatus = omittedNativeObservations > 0 || omittedCandidates > 0
208
+ ? "truncated"
209
+ : managed.coverage.state === "complete" && native.unsupported === 0
210
+ ? "complete-within-inputs"
211
+ : "partial";
212
+ return {
213
+ schema_version: 1,
214
+ algorithm: {
215
+ name: "rea-managed-native-verification",
216
+ version: 1,
217
+ token_identity: "build-local",
218
+ token_to_address_mapping: "not-inferred",
219
+ },
220
+ managed_boundary: {
221
+ evidence_id: managedEvidence.evidence_id,
222
+ artifact_sha256: managed.artifact.sha256,
223
+ artifact_path: managed.artifact.path,
224
+ mvid: managed.module?.mvid ?? null,
225
+ metadata_status: managed.metadata.status,
226
+ pinvoke_imports_total: managed.pinvoke_imports.total,
227
+ native_implementations_total: managed.native_implementations.total,
228
+ coverage_state: managed.coverage.state,
229
+ },
230
+ native_observations: {
231
+ total: input.native_observations.length,
232
+ accepted: native.accepted,
233
+ unsupported: native.unsupported,
234
+ symbols: native.symbols.length,
235
+ truncated: omittedNativeObservations > 0,
236
+ },
237
+ summary: {
238
+ ...counts,
239
+ native_body_unresolved: nativeBodyUnresolved,
240
+ },
241
+ pinvoke_imports: [...pinvokeImports],
242
+ native_implementations: {
243
+ unresolved: nativeBodyUnresolved,
244
+ reason: "Managed metadata tokens and RVAs are not translated to native provider addresses by this workflow; C++/CLI, ReadyToRun, and native-body mappings require explicit provider-supported bridge evidence.",
245
+ },
246
+ coverage: {
247
+ status: coverageStatus,
248
+ omitted_native_observations: omittedNativeObservations,
249
+ omitted_candidates: omittedCandidates,
250
+ },
251
+ evidence_links: [
252
+ managedEvidence.evidence_id,
253
+ ...input.native_observations
254
+ .slice(0, input.limits.max_native_observations)
255
+ .map(({ evidence_id: id }) => id),
256
+ ],
257
+ limitations: [
258
+ "P/Invoke verification checks declared import names against supplied native export or function-name Evidence only.",
259
+ "A matching native symbol verifies that a candidate export/function was observed; it does not prove CLR binding, marshaling behavior, call reachability, or runtime loading.",
260
+ "Missing supplied native symbols are reported as unresolved, not proof that a dependency cannot exist.",
261
+ "Managed metadata tokens and method RVAs are not interpreted as native addresses.",
262
+ ...(managed.coverage.state === "complete"
263
+ ? []
264
+ : ["Managed boundary input is partial or unavailable."]),
265
+ ...(native.unsupported === 0
266
+ ? []
267
+ : [
268
+ "Some native Evidence operations were unsupported by this workflow.",
269
+ ]),
270
+ ],
271
+ };
272
+ };
@@ -0,0 +1,141 @@
1
+ import { z } from "zod";
2
+ import { evidenceSchema } from "./evidence.js";
3
+ import { cliMetadataGuidSchema } from "./managedArtifact.js";
4
+ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
5
+ const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
6
+ const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
7
+ const boundedTextSchema = z.string().min(1).max(4_096);
8
+ const matchStatusSchema = z.enum([
9
+ "verified",
10
+ "inferred",
11
+ "unresolved",
12
+ "contradicted",
13
+ ]);
14
+ const matchBasisSchema = z.enum([
15
+ "exact-export-name",
16
+ "exact-function-name",
17
+ "decorated-name-candidate",
18
+ "module-mismatch",
19
+ "no-native-candidate",
20
+ "unsupported-native-evidence",
21
+ ]);
22
+ const nativeVerificationLimitsSchema = z.strictObject({
23
+ max_native_observations: z.number().int().min(1).max(50).default(20),
24
+ max_candidates_per_import: z.number().int().min(1).max(100).default(25),
25
+ });
26
+ const nativeSymbolSchema = z.strictObject({
27
+ evidence_id: evidenceIdSchema,
28
+ operation: z.string().min(1),
29
+ name: z.string().min(1),
30
+ address: z.string().nullable(),
31
+ module_name: z.string().nullable(),
32
+ module_path: z.string().nullable(),
33
+ source: z.enum(["macho-export", "function-dossier"]),
34
+ });
35
+ export const pinvokeVerificationSchema = z.strictObject({
36
+ item_id: z.string().regex(/^mnv_pinvoke_[a-f0-9]{64}$/u),
37
+ managed: z.strictObject({
38
+ token: tokenSchema,
39
+ member_token: tokenSchema.nullable(),
40
+ member_name: z.string().nullable(),
41
+ import_name: z.string().min(1),
42
+ import_scope_name: z.string().nullable(),
43
+ no_mangle: z.boolean(),
44
+ char_set: z.enum(["not-specified", "ansi", "unicode", "auto", "unknown"]),
45
+ call_convention: z.enum([
46
+ "not-specified",
47
+ "winapi",
48
+ "cdecl",
49
+ "stdcall",
50
+ "thiscall",
51
+ "fastcall",
52
+ "unknown",
53
+ ]),
54
+ declaration_verification: z.literal("managed-declaration-only"),
55
+ }),
56
+ status: matchStatusSchema,
57
+ basis: matchBasisSchema,
58
+ confidence: z.enum(["observed", "inferred", "unknown"]),
59
+ matched_native: nativeSymbolSchema.nullable(),
60
+ candidates: z.array(nativeSymbolSchema).max(100),
61
+ evidence_links: z.array(evidenceIdSchema).min(1).max(51),
62
+ limitations: z.array(boundedTextSchema).max(100),
63
+ });
64
+ /** Authenticated managed boundary Evidence plus native observations. */
65
+ export const managedNativeVerificationInputSchema = z
66
+ .strictObject({
67
+ managed_boundaries: evidenceSchema,
68
+ native_observations: z.array(evidenceSchema).min(1).max(50),
69
+ limits: nativeVerificationLimitsSchema.default({
70
+ max_native_observations: 20,
71
+ max_candidates_per_import: 25,
72
+ }),
73
+ unknown_registry_approved: z.literal(true).optional(),
74
+ })
75
+ .superRefine((input, context) => {
76
+ const ids = new Set();
77
+ for (const [index, evidence] of input.native_observations.entries()) {
78
+ if (evidence.evidence_id === input.managed_boundaries.evidence_id) {
79
+ context.addIssue({
80
+ code: "custom",
81
+ path: ["native_observations", index],
82
+ message: "Native observation Evidence must be distinct from managed boundary Evidence",
83
+ });
84
+ }
85
+ if (ids.has(evidence.evidence_id)) {
86
+ context.addIssue({
87
+ code: "custom",
88
+ path: ["native_observations", index],
89
+ message: "Native observation Evidence IDs must be unique",
90
+ });
91
+ }
92
+ ids.add(evidence.evidence_id);
93
+ }
94
+ });
95
+ /** Provider-neutral managed/native verification result. */
96
+ export const managedNativeVerificationResultSchema = z.strictObject({
97
+ schema_version: z.literal(1),
98
+ verification_id: z.string().regex(/^mnv_[a-f0-9]{64}$/u),
99
+ algorithm: z.strictObject({
100
+ name: z.literal("rea-managed-native-verification"),
101
+ version: z.literal(1),
102
+ token_identity: z.literal("build-local"),
103
+ token_to_address_mapping: z.literal("not-inferred"),
104
+ }),
105
+ managed_boundary: z.strictObject({
106
+ evidence_id: evidenceIdSchema,
107
+ artifact_sha256: digestSchema,
108
+ artifact_path: z.string().min(1),
109
+ mvid: cliMetadataGuidSchema.nullable(),
110
+ metadata_status: z.enum(["absent", "complete", "partial", "malformed"]),
111
+ pinvoke_imports_total: z.number().int().min(0),
112
+ native_implementations_total: z.number().int().min(0),
113
+ coverage_state: z.enum(["complete", "partial", "unavailable"]),
114
+ }),
115
+ native_observations: z.strictObject({
116
+ total: z.number().int().min(1),
117
+ accepted: z.number().int().min(0),
118
+ unsupported: z.number().int().min(0),
119
+ symbols: z.number().int().min(0),
120
+ truncated: z.boolean(),
121
+ }),
122
+ summary: z.strictObject({
123
+ verified: z.number().int().min(0),
124
+ inferred: z.number().int().min(0),
125
+ unresolved: z.number().int().min(0),
126
+ contradicted: z.number().int().min(0),
127
+ native_body_unresolved: z.number().int().min(0),
128
+ }),
129
+ pinvoke_imports: z.array(pinvokeVerificationSchema).max(50_000),
130
+ native_implementations: z.strictObject({
131
+ unresolved: z.number().int().min(0),
132
+ reason: boundedTextSchema,
133
+ }),
134
+ coverage: z.strictObject({
135
+ status: z.enum(["complete-within-inputs", "partial", "truncated"]),
136
+ omitted_native_observations: z.number().int().min(0),
137
+ omitted_candidates: z.number().int().min(0),
138
+ }),
139
+ evidence_links: z.array(evidenceIdSchema).min(2).max(51),
140
+ limitations: z.array(boundedTextSchema).max(1_000),
141
+ });
@@ -0,0 +1,196 @@
1
+ import { createHash } from "node:crypto";
2
+ import canonicalize from "canonicalize";
3
+ import { z } from "zod";
4
+ import { evidenceSchema, parseEvidence } from "./evidence.js";
5
+ import { cliMetadataGuidSchema, managedMemberInspectionSchema, } from "./managedArtifact.js";
6
+ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
7
+ const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
8
+ const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
9
+ const boundedTextSchema = z.string().min(1).max(65_536);
10
+ const boundedLabelSchema = z.string().min(1).max(512);
11
+ const decompilerSchema = z.strictObject({
12
+ name: boundedLabelSchema,
13
+ version: z.string().min(1).max(128).nullable(),
14
+ family: z.enum(["ilspy", "dnspy", "dnlib", "mono-cecil", "other"]),
15
+ executable_sha256: digestSchema.nullable(),
16
+ options: z.array(z.string().max(512)).max(50).default([]),
17
+ });
18
+ const managedReconstructionMethodInputSchema = z.strictObject({
19
+ token: tokenSchema,
20
+ signature_sha256: digestSchema,
21
+ normalized_il_sha256: digestSchema.nullable(),
22
+ reconstruction: z.strictObject({
23
+ kind: z.enum(["decompiled-csharp", "decompiled-il", "semantic-pseudocode"]),
24
+ language: z.enum(["csharp", "il", "pseudocode"]),
25
+ text: boundedTextSchema,
26
+ text_sha256: digestSchema.optional(),
27
+ source_path: z.string().min(1).max(4_096).nullable().optional(),
28
+ start_line: z.number().int().min(1).nullable().optional(),
29
+ end_line: z.number().int().min(1).nullable().optional(),
30
+ }),
31
+ });
32
+ export const managedReconstructionImportInputSchema = z.strictObject({
33
+ static_members: evidenceSchema,
34
+ decompiler: decompilerSchema,
35
+ methods: z.array(managedReconstructionMethodInputSchema).min(1).max(50),
36
+ notes: z.array(z.string().min(1).max(4_096)).max(100).default([]),
37
+ unknown_registry_approved: z.literal(true).optional(),
38
+ });
39
+ const importedMethodSchema = z.strictObject({
40
+ token: tokenSchema,
41
+ declaring_type: z.string().nullable(),
42
+ name: z.string(),
43
+ signature_sha256: digestSchema,
44
+ normalized_il_sha256: digestSchema.nullable(),
45
+ body_sha256: digestSchema.nullable(),
46
+ il_size: z.number().int().min(0),
47
+ reconstruction: z.strictObject({
48
+ kind: z.enum(["decompiled-csharp", "decompiled-il", "semantic-pseudocode"]),
49
+ language: z.enum(["csharp", "il", "pseudocode"]),
50
+ text: boundedTextSchema,
51
+ text_sha256: digestSchema,
52
+ text_length: z.number().int().min(1).max(65_536),
53
+ line_count: z.number().int().min(1),
54
+ source_path: z.string().min(1).max(4_096).nullable(),
55
+ start_line: z.number().int().min(1).nullable(),
56
+ end_line: z.number().int().min(1).nullable(),
57
+ }),
58
+ validation: z.strictObject({
59
+ matched_static_member: z.literal(true),
60
+ exact_build_required: z.literal(true),
61
+ canonical_observation: z.literal(false),
62
+ confidence_floor: z.literal("inference"),
63
+ }),
64
+ });
65
+ export const managedReconstructionImportResultSchema = z.strictObject({
66
+ schema_version: z.literal(1),
67
+ reconstruction_id: z.string().regex(/^mre_[a-f0-9]{64}$/u),
68
+ phase: z.literal("reconstruction-import"),
69
+ executed: z.literal(false),
70
+ static_observation: z.strictObject({
71
+ evidence_id: evidenceIdSchema,
72
+ artifact_sha256: digestSchema,
73
+ artifact_path: z.string().min(1),
74
+ byte_length: z.number().int().min(0),
75
+ module_name: z.string().nullable(),
76
+ mvid: cliMetadataGuidSchema.nullable(),
77
+ metadata_status: z.enum(["absent", "complete", "partial", "malformed"]),
78
+ }),
79
+ decompiler: decompilerSchema.extend({
80
+ options_sha256: digestSchema,
81
+ }),
82
+ summary: z.strictObject({
83
+ imported_methods: z.number().int().min(1).max(50),
84
+ decompiled_csharp_methods: z.number().int().min(0).max(50),
85
+ decompiled_il_methods: z.number().int().min(0).max(50),
86
+ pseudocode_methods: z.number().int().min(0).max(50),
87
+ total_text_bytes: z.number().int().min(1),
88
+ }),
89
+ methods: z.array(importedMethodSchema).min(1).max(50),
90
+ notes: z.array(z.string().min(1).max(4_096)).max(100),
91
+ evidence_links: z.array(evidenceIdSchema).length(1),
92
+ limitations: z.array(z.string().min(1).max(4_096)).max(1_000),
93
+ });
94
+ const sha256Text = (value) => createHash("sha256").update(value).digest("hex");
95
+ const sha256Json = (value) => {
96
+ const serialized = canonicalize(value);
97
+ if (serialized === undefined)
98
+ throw new TypeError("Managed reconstruction canonicalization failed");
99
+ return createHash("sha256").update(serialized).digest("hex");
100
+ };
101
+ const countLines = (text) => text.length === 0 ? 0 : text.split(/\r\n|\r|\n/u).length;
102
+ const findObservedMethod = (members, candidate) => members.methods.items.find((item) => item.token === candidate.token &&
103
+ item.signature.raw_sha256 === candidate.signature_sha256 &&
104
+ item.body.status === "present" &&
105
+ item.body.normalized_il_sha256 !== null &&
106
+ candidate.normalized_il_sha256 !== null &&
107
+ item.body.normalized_il_sha256 === candidate.normalized_il_sha256);
108
+ const verifyTextSha256 = (candidate, textSha256) => {
109
+ if (candidate.reconstruction.text_sha256 !== undefined &&
110
+ candidate.reconstruction.text_sha256 !== textSha256)
111
+ throw new TypeError(`Reconstruction text hash mismatch for ${candidate.token}`);
112
+ };
113
+ const buildImportedMethod = (observed, candidate, textSha256) => ({
114
+ token: observed.token,
115
+ declaring_type: observed.declaring_type,
116
+ name: observed.name,
117
+ signature_sha256: observed.signature.raw_sha256,
118
+ normalized_il_sha256: observed.body.normalized_il_sha256,
119
+ body_sha256: observed.body.il_sha256,
120
+ il_size: observed.body.il_size,
121
+ reconstruction: {
122
+ kind: candidate.reconstruction.kind,
123
+ language: candidate.reconstruction.language,
124
+ text: candidate.reconstruction.text,
125
+ text_sha256: textSha256,
126
+ text_length: candidate.reconstruction.text.length,
127
+ line_count: countLines(candidate.reconstruction.text),
128
+ source_path: candidate.reconstruction.source_path ?? null,
129
+ start_line: candidate.reconstruction.start_line ?? null,
130
+ end_line: candidate.reconstruction.end_line ?? null,
131
+ },
132
+ validation: {
133
+ matched_static_member: true,
134
+ exact_build_required: true,
135
+ canonical_observation: false,
136
+ confidence_floor: "inference",
137
+ },
138
+ });
139
+ const buildReconstructionSummary = (methods) => ({
140
+ imported_methods: methods.length,
141
+ decompiled_csharp_methods: methods.filter(({ reconstruction }) => reconstruction.kind === "decompiled-csharp").length,
142
+ decompiled_il_methods: methods.filter(({ reconstruction }) => reconstruction.kind === "decompiled-il").length,
143
+ pseudocode_methods: methods.filter(({ reconstruction }) => reconstruction.kind === "semantic-pseudocode").length,
144
+ total_text_bytes: methods.reduce((total, { reconstruction }) => total + reconstruction.text_length, 0),
145
+ });
146
+ const buildStaticObservation = (staticEvidence, members) => ({
147
+ evidence_id: staticEvidence.evidence_id,
148
+ artifact_sha256: members.artifact.sha256,
149
+ artifact_path: members.artifact.path,
150
+ byte_length: members.artifact.byte_length,
151
+ module_name: members.module?.name ?? null,
152
+ mvid: members.module?.mvid ?? null,
153
+ metadata_status: members.metadata.status,
154
+ });
155
+ const buildDecompilerRecord = (decompiler) => ({
156
+ ...decompiler,
157
+ options_sha256: sha256Json(decompiler.options),
158
+ });
159
+ const RECONSTRUCTION_LIMITATIONS = [
160
+ "Decompiler output is imported as reconstruction evidence and analyst inference; metadata and IL observations remain canonical.",
161
+ "This operation did not execute, load, reflect over, debug, instrument, patch, or decompile the target artifact.",
162
+ "The imported reconstruction is valid only for the exact artifact SHA-256, MVID, method signature, and normalized IL shape recorded here.",
163
+ "Obfuscated names, decompiler variables, and control-flow restructuring are not treated as proof without separate validation.",
164
+ ];
165
+ const buildReconstructionWithoutId = (input, staticEvidence, members, methods) => ({
166
+ schema_version: 1,
167
+ phase: "reconstruction-import",
168
+ executed: false,
169
+ static_observation: buildStaticObservation(staticEvidence, members),
170
+ decompiler: buildDecompilerRecord(input.decompiler),
171
+ summary: buildReconstructionSummary(methods),
172
+ methods: [...methods],
173
+ notes: input.notes,
174
+ evidence_links: [staticEvidence.evidence_id],
175
+ limitations: RECONSTRUCTION_LIMITATIONS,
176
+ });
177
+ /** Authenticate decompiler reconstruction against static IL Evidence. */
178
+ export const importManagedReconstruction = (input) => {
179
+ const staticEvidence = parseEvidence(input.static_members);
180
+ if (staticEvidence.operation !== "inspect_managed_members")
181
+ throw new TypeError("Evidence operation is not inspect_managed_members");
182
+ const members = managedMemberInspectionSchema.parse(staticEvidence.normalized_result);
183
+ const methods = input.methods.map((candidate) => {
184
+ const observed = findObservedMethod(members, candidate);
185
+ if (observed === undefined)
186
+ throw new TypeError(`Reconstruction method lock ${candidate.token} does not match a static managed member observation`);
187
+ const textSha256 = sha256Text(candidate.reconstruction.text);
188
+ verifyTextSha256(candidate, textSha256);
189
+ return buildImportedMethod(observed, candidate, textSha256);
190
+ });
191
+ const withoutId = buildReconstructionWithoutId(input, staticEvidence, members, methods);
192
+ return managedReconstructionImportResultSchema.parse({
193
+ ...withoutId,
194
+ reconstruction_id: `mre_${sha256Json(withoutId)}`,
195
+ });
196
+ };