rea-agents 6.0.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (611) hide show
  1. package/README.md +26 -18
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +205 -51
  4. package/bridge/hopper_bridge.py +314 -127
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +274 -31
  10. package/dist/android/JadxMcpTransport.js +18 -2
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +76 -37
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/BinaryTargetResolver.js +5 -3
  18. package/dist/application/BrowserEvidence.js +3 -8
  19. package/dist/application/BrowserScenarioEvidence.js +2 -18
  20. package/dist/application/CallPathTracing.js +19 -3
  21. package/dist/application/CapabilityInventory.js +48 -11
  22. package/dist/application/ClientConfigurationDocument.js +917 -8
  23. package/dist/application/ClientRegistrationIdentity.js +26 -5
  24. package/dist/application/ClientRegistrationStatus.js +29 -14
  25. package/dist/application/DirectAnalysis.js +56 -51
  26. package/dist/application/DirectAnalysisCleanup.js +72 -0
  27. package/dist/application/DirectAnalysisStatus.js +4 -5
  28. package/dist/application/Doctor.js +19 -21
  29. package/dist/application/DoctorDiagnostics.js +1 -2
  30. package/dist/application/DoctorScope.js +25 -13
  31. package/dist/application/EnhancedLiteralTracing.js +22 -25
  32. package/dist/application/EnhancedTools.js +64 -17
  33. package/dist/application/EvidenceBundleFiles.js +30 -13
  34. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  35. package/dist/application/InventoryProjectionEvidence.js +4 -3
  36. package/dist/application/InvestigationProviders.js +11 -2
  37. package/dist/application/JsonFiles.js +83 -28
  38. package/dist/application/LinuxHopper.js +9 -6
  39. package/dist/application/MacHopper.js +15 -18
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/RealHopperAssertions.js +0 -11
  42. package/dist/application/ReconstructionCoverageService.js +7 -4
  43. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  44. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  45. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  46. package/dist/application/Setup.js +21 -17
  47. package/dist/application/SetupClientConfiguration.js +10 -15
  48. package/dist/application/SetupHost.js +21 -29
  49. package/dist/application/SetupPlan.js +11 -9
  50. package/dist/application/SupportedClients.js +34 -1
  51. package/dist/application/Uninstall.js +82 -29
  52. package/dist/application/Update.js +18 -3
  53. package/dist/application/UpdateMaintenance.js +7 -5
  54. package/dist/application/UpdateRuntime.js +57 -36
  55. package/dist/application/WebModuleTraceService.js +4 -2
  56. package/dist/application/WebNetworkCaptureService.js +4 -2
  57. package/dist/application/WebRuntimeService.js +5 -3
  58. package/dist/application/WebScriptExportService.js +32 -6
  59. package/dist/application/WebSourceLocationService.js +4 -2
  60. package/dist/application/WorkflowEvidence.js +105 -0
  61. package/dist/application/XrefsAddressResolution.js +45 -0
  62. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  63. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  64. package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
  65. package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
  66. package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
  67. package/dist/application/binary/BinarySession.js +161 -93
  68. package/dist/application/binary/BinarySessionComposition.js +1 -3
  69. package/dist/application/binary/BinarySessionExecution.js +3 -5
  70. package/dist/application/binary/BinarySessionOpen.js +4 -4
  71. package/dist/application/binary/BinarySessionRecords.js +26 -4
  72. package/dist/application/binary/BinarySessionStatus.js +18 -7
  73. package/dist/application/binary/CompositeProvider.js +16 -17
  74. package/dist/application/binary/LazyAnalysisProvider.js +8 -5
  75. package/dist/application/binary/SessionProviderRouter.js +27 -135
  76. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  77. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  78. package/dist/application/evm/EvmInterfaceService.js +4 -2
  79. package/dist/application/homebrew.js +48 -0
  80. package/dist/application/investigation/EvidenceLedger.js +21 -7
  81. package/dist/application/investigation/InvestigationRecords.js +8 -0
  82. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  83. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  84. package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
  85. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  86. package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
  87. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  88. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
  89. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
  90. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  91. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  92. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  93. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  95. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
  96. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
  97. package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
  98. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  99. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
  100. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  101. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  102. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  103. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  104. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  105. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  106. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  107. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  108. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
  109. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  110. package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
  111. package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
  112. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  113. package/dist/application/process/ProcessCli.js +25 -17
  114. package/dist/application/process/ProcessEvidence.js +4 -4
  115. package/dist/application/workflowInputError.js +18 -0
  116. package/dist/artifacts/ArtifactProvider.js +48 -13
  117. package/dist/artifacts/ArtifactReader.js +31 -0
  118. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  119. package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
  120. package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
  121. package/dist/artifacts/SafeOutputTree.js +16 -2
  122. package/dist/artifacts/ZipArtifactReader.js +11 -4
  123. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
  124. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  125. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  126. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  127. package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
  128. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  129. package/dist/artifacts/apple/NibArchive.js +81 -14
  130. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  131. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  132. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  133. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
  134. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  135. package/dist/artifacts/inventory/reader.js +3 -3
  136. package/dist/artifacts/inventory/scanCanonical.js +59 -38
  137. package/dist/artifacts/inventory/scanReader.js +5 -9
  138. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  139. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  140. package/dist/browser/CdpBrowserProvider.js +2 -3
  141. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  142. package/dist/browser/CdpCaptureEventHandlers.js +78 -15
  143. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  144. package/dist/browser/CdpCaptureEvents.js +25 -1
  145. package/dist/browser/CdpCaptureValues.js +20 -0
  146. package/dist/browser/CdpConnection.js +30 -11
  147. package/dist/browser/CdpElectronProvider.js +0 -2
  148. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  149. package/dist/browser/CdpElectronScripts.js +2 -3
  150. package/dist/browser/CdpOptionalCommand.js +2 -3
  151. package/dist/browser/CdpPageCapture.js +23 -1
  152. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  153. package/dist/browser/CdpSafeMetadata.js +10 -10
  154. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  155. package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
  156. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  157. package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
  158. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  159. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  160. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  161. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  162. package/dist/browser/WebSourceMapFetcher.js +426 -72
  163. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  164. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  165. package/dist/browser/history/CaptureFailures.js +41 -1
  166. package/dist/browser/history/CaptureRelease.js +5 -0
  167. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  168. package/dist/browser/history/HarJson.js +3 -2
  169. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  170. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  171. package/dist/catalogIdentity.js +0 -1
  172. package/dist/cli/analysisSelector.js +23 -0
  173. package/dist/cli/analysisViewCommands.js +36 -0
  174. package/dist/cli/applicationCommands.js +2 -3
  175. package/dist/cli/artifactCommands.js +11 -12
  176. package/dist/cli/coreAnalysisCommands.js +3 -3
  177. package/dist/cli/coreBinaryCommands.js +100 -37
  178. package/dist/cli/coreNativeCommands.js +9 -10
  179. package/dist/cli/electronCommands.js +10 -9
  180. package/dist/cli/interactiveSetup.js +6 -6
  181. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  182. package/dist/cli/jsonOutput.js +4 -99
  183. package/dist/cli/managedCommands.js +7 -8
  184. package/dist/cli/nativeCallCommands.js +3 -5
  185. package/dist/cli/omittableDefaults.js +50 -0
  186. package/dist/cli/processCommands.js +3 -2
  187. package/dist/cli/setupCommands.js +16 -15
  188. package/dist/cli/utilityCommands.js +9 -9
  189. package/dist/cli/webRuntimeCommands.js +8 -8
  190. package/dist/cli.js +18 -9
  191. package/dist/cliBrowserScenarioCommands.js +2 -2
  192. package/dist/cliCommandNames.js +1 -1
  193. package/dist/cliJsonInput.js +24 -5
  194. package/dist/cliOutput.js +0 -38
  195. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  196. package/dist/composition/binary.js +9 -9
  197. package/dist/composition/browserScenario.js +2 -1
  198. package/dist/composition/directAnalysis.js +20 -13
  199. package/dist/composition/electronScenario.js +1 -1
  200. package/dist/composition/optionalObservationProviders.js +12 -7
  201. package/dist/config/environment.js +10 -0
  202. package/dist/config/ghidraStartupTimeout.js +12 -0
  203. package/dist/config/homeDirectory.js +12 -0
  204. package/dist/config/mcpResponseBudget.js +30 -0
  205. package/dist/config/parseConfig.js +8 -3
  206. package/dist/config/parsers.js +19 -22
  207. package/dist/contracts/analysisViewToolContracts.js +56 -0
  208. package/dist/contracts/applicationToolContracts.js +5 -4
  209. package/dist/contracts/artifactComparisonExample.js +2 -2
  210. package/dist/contracts/artifactToolContracts.js +1 -1
  211. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  212. package/dist/contracts/browserToolContracts.js +19 -15
  213. package/dist/contracts/enhancedInputs.js +7 -5
  214. package/dist/contracts/enhancedToolContracts.js +7 -6
  215. package/dist/contracts/evm/evmToolContracts.js +1 -1
  216. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  217. package/dist/contracts/hopperMemoryContracts.js +2 -5
  218. package/dist/contracts/inputSchemaPresentation.js +90 -0
  219. package/dist/contracts/investigationExamples.js +4 -3
  220. package/dist/contracts/javascript/electronToolContracts.js +2 -2
  221. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  222. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  223. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  224. package/dist/contracts/managed/managedToolContracts.js +7 -14
  225. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  226. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  227. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  228. package/dist/contracts/native/nativeToolContracts.js +5 -3
  229. package/dist/contracts/officialToolContracts.js +16 -16
  230. package/dist/contracts/promptContracts.js +5 -5
  231. package/dist/contracts/providerSelection.js +1 -1
  232. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  233. package/dist/contracts/sessionStatusContract.js +2 -4
  234. package/dist/contracts/sessionToolContracts.js +18 -8
  235. package/dist/contracts/sessionToolSchemas.js +3 -19
  236. package/dist/contracts/toolContractExamples.js +0 -1
  237. package/dist/contracts/toolContractHelpers.js +4 -1
  238. package/dist/contracts/toolContracts.js +2 -0
  239. package/dist/contracts/toolEffects.js +1 -1
  240. package/dist/contracts/toolOutputSchemaGroups.js +160 -115
  241. package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
  242. package/dist/contracts/toolSchemaMetadata.js +41 -33
  243. package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
  244. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  245. package/dist/contracts/webScriptToolContracts.js +1 -1
  246. package/dist/doctorRuntime.js +7 -5
  247. package/dist/domain/analysisErrorBase.js +8 -3
  248. package/dist/domain/analysisErrorCore.js +6 -1
  249. package/dist/domain/analysisErrorPresentation.js +90 -20
  250. package/dist/domain/analysisErrorProjection.js +130 -32
  251. package/dist/domain/analysisSnapshot.js +29 -31
  252. package/dist/domain/analysisView/analysisView.js +243 -0
  253. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  254. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  255. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  256. package/dist/domain/android/androidAnalysis.js +2 -4
  257. package/dist/domain/android/androidApplication.js +18 -10
  258. package/dist/domain/apple/appleApplication.js +42 -15
  259. package/dist/domain/apple/dyldEnvironment.js +73 -0
  260. package/dist/domain/apple/dylibResolution.js +130 -12
  261. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  262. package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
  263. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  264. package/dist/domain/apple/keyedArchive.js +35 -3
  265. package/dist/domain/apple/machoContainer.js +54 -0
  266. package/dist/domain/apple/plistNumbers.js +76 -0
  267. package/dist/domain/artifactComparison.js +15 -6
  268. package/dist/domain/artifactGraph.js +16 -3
  269. package/dist/domain/artifactIdentity.js +29 -0
  270. package/dist/domain/artifactInventoryEvidence.js +28 -40
  271. package/dist/domain/artifactOperationError.js +3 -3
  272. package/dist/domain/artifactPartialObservation.js +1 -0
  273. package/dist/domain/artifactPathSyntax.js +49 -0
  274. package/dist/domain/binaryTarget.js +39 -13
  275. package/dist/domain/bridgeCandidateProjection.js +71 -0
  276. package/dist/domain/browserCaptureComparison.js +13 -49
  277. package/dist/domain/browserCompleteness.js +1 -0
  278. package/dist/domain/browserNetworkEvidence.js +10 -4
  279. package/dist/domain/browserObservation.js +0 -1
  280. package/dist/domain/browserObservationError.js +24 -5
  281. package/dist/domain/browserObservationSchemas.js +14 -3
  282. package/dist/domain/browserScenario.js +0 -1
  283. package/dist/domain/browserScenarioCapture.js +1 -2
  284. package/dist/domain/browserScenarioDiff.js +0 -2
  285. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  286. package/dist/domain/browserScenarioDiffValues.js +2 -2
  287. package/dist/domain/browserScenarioValues.js +5 -10
  288. package/dist/domain/bundleComparison.js +3 -2
  289. package/dist/domain/callPath.js +8 -9
  290. package/dist/domain/callPathSchemas.js +2 -2
  291. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  292. package/dist/domain/canonicalOrdering.js +9 -5
  293. package/dist/domain/changedBehavior.js +9 -9
  294. package/dist/domain/comparisonSourceEvidence.js +40 -0
  295. package/dist/domain/completionLedgerGeneration.js +2 -1
  296. package/dist/domain/configurationErrors.js +13 -1
  297. package/dist/domain/conformancePackage.js +4 -3
  298. package/dist/domain/evidence.js +65 -36
  299. package/dist/domain/evidenceBundle.js +47 -8
  300. package/dist/domain/evidenceCompletionLedger.js +2 -1
  301. package/dist/domain/evidenceErrors.js +12 -1
  302. package/dist/domain/explicitSensitiveFailure.js +17 -1
  303. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  304. package/dist/domain/functionComparison.js +4 -5
  305. package/dist/domain/functionComparisonDimensions.js +120 -87
  306. package/dist/domain/functionComparisonNormalization.js +23 -34
  307. package/dist/domain/functionComparisonResults.js +1 -4
  308. package/dist/domain/functionComparisonSchemas.js +2 -8
  309. package/dist/domain/functionDossierEvidence.js +2 -37
  310. package/dist/domain/hopperErrors.js +23 -2
  311. package/dist/domain/hopperValues.js +51 -8
  312. package/dist/domain/immutableJson.js +114 -0
  313. package/dist/domain/inputIssueProjection.js +3 -0
  314. package/dist/domain/javascript/electronActiveObservation.js +47 -64
  315. package/dist/domain/javascript/electronObservation.js +14 -3
  316. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  317. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  318. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  319. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  320. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  321. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  322. package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
  323. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  324. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  325. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  326. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  327. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  328. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  329. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  330. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  331. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  332. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  333. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  334. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  335. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  336. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  337. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  338. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  339. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  340. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  341. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  342. package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
  343. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  344. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  345. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  346. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  347. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  348. package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
  349. package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
  350. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  351. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  352. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  353. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  354. package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
  355. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  356. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  357. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  358. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  359. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  360. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  361. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  362. package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
  363. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  364. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  365. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  366. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  367. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
  368. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  369. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
  370. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  371. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  372. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  373. package/dist/domain/jsonSerialization.js +109 -0
  374. package/dist/domain/jsonValue.js +90 -6
  375. package/dist/domain/localPath.js +6 -0
  376. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  377. package/dist/domain/managed/managedArtifact.js +6 -4
  378. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  379. package/dist/domain/managed/managedMemberComparison.js +2 -9
  380. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  381. package/dist/domain/managed/managedNativeVerification.js +3 -11
  382. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  383. package/dist/domain/native/binaryLayout.js +2 -3
  384. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  385. package/dist/domain/native/nativeApiBoundary.js +1 -1
  386. package/dist/domain/native/nativeCallObservation.js +37 -13
  387. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  388. package/dist/domain/native/nativeInstruction.js +7 -0
  389. package/dist/domain/native/recordedCrash.js +2 -3
  390. package/dist/domain/offsetDateTime.js +17 -0
  391. package/dist/domain/process/processCapture.js +21 -16
  392. package/dist/domain/process/processCaptureCoverage.js +67 -0
  393. package/dist/domain/process/processCaptureExample.js +2 -1
  394. package/dist/domain/process/processCaptureParsing.js +1 -34
  395. package/dist/domain/process/processCaptureValidation.js +81 -13
  396. package/dist/domain/process/processComparison.js +79 -26
  397. package/dist/domain/process/processObservation.js +10 -2
  398. package/dist/domain/process/processScenario.js +35 -12
  399. package/dist/domain/process/processTraceComparison.js +0 -2
  400. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  401. package/dist/domain/process/processTraceEvaluation.js +15 -11
  402. package/dist/domain/process/processTraceSpecification.js +3 -4
  403. package/dist/domain/propertyListKeys.js +1 -1
  404. package/dist/domain/propertyListXmlText.js +19 -0
  405. package/dist/domain/providerAdapterError.js +3 -1
  406. package/dist/domain/providerOperationHealth.js +54 -0
  407. package/dist/domain/reconstructionCoverage.js +5 -2
  408. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  409. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  410. package/dist/domain/reconstructionVerification.js +9 -46
  411. package/dist/domain/reconstructionVerificationSchemas.js +4 -3
  412. package/dist/domain/referenceSourceGraph.js +20 -21
  413. package/dist/domain/staticRuntimeCorrelation.js +8 -45
  414. package/dist/domain/stringPatterns.js +6 -0
  415. package/dist/domain/swiftSymbolClassification.js +61 -0
  416. package/dist/domain/symbolAnalysis.js +66 -18
  417. package/dist/domain/webBundleAnalysis.js +20 -8
  418. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  419. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  420. package/dist/domain/webCaptureDiff.js +0 -1
  421. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  422. package/dist/domain/webEventListeners.js +3 -2
  423. package/dist/domain/webExecution.js +3 -2
  424. package/dist/domain/webRuntime.js +19 -7
  425. package/dist/domain/webScriptExport.js +1 -1
  426. package/dist/domain/webSourceLocation.js +1 -0
  427. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  428. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  429. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  430. package/dist/dotnet/ManagedMemberRows.js +75 -62
  431. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  432. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  433. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  434. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  435. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  436. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  437. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  438. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  439. package/dist/evaluation/CodexAgentEval.js +12 -8
  440. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  441. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  442. package/dist/firmware/FirmwareCommand.js +9 -5
  443. package/dist/firmware/FirmwareFiles.js +1 -1
  444. package/dist/firmware/FirmwareProvider.js +4 -4
  445. package/dist/generatedPackageMetadata.js +2 -2
  446. package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
  447. package/dist/ghidra/GhidraClient.js +126 -34
  448. package/dist/ghidra/GhidraClientStartup.js +0 -2
  449. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  450. package/dist/ghidra/GhidraDoctor.js +6 -5
  451. package/dist/ghidra/GhidraFunctionValues.js +13 -12
  452. package/dist/ghidra/GhidraInstallation.js +58 -33
  453. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  454. package/dist/ghidra/GhidraJavaLaunch.js +66 -0
  455. package/dist/ghidra/GhidraLauncher.js +47 -22
  456. package/dist/ghidra/GhidraProvider.js +6 -2
  457. package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
  458. package/dist/ghidra/GhidraProviderClient.js +36 -15
  459. package/dist/ghidra/GhidraSessionError.js +13 -7
  460. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  461. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  462. package/dist/ghidra/GhidraTransport.js +20 -0
  463. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  464. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  465. package/dist/hopper/BridgeLauncher.js +65 -56
  466. package/dist/hopper/HopperAnalysisProfile.js +65 -12
  467. package/dist/hopper/HopperCleanup.js +63 -22
  468. package/dist/hopper/HopperClient.js +288 -59
  469. package/dist/hopper/HopperFileOffset.js +237 -0
  470. package/dist/hopper/HopperMachOImage.js +197 -0
  471. package/dist/hopper/HopperOperationStage.js +6 -0
  472. package/dist/hopper/HopperProvider.js +71 -19
  473. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  474. package/dist/hopper/HopperRegexSearch.js +134 -0
  475. package/dist/hopper/HopperRegexWorker.js +27 -0
  476. package/dist/hopper/HopperRequestQueue.js +68 -19
  477. package/dist/hopper/HopperTargetLease.js +133 -49
  478. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  479. package/dist/ida/IdaConfiguration.js +8 -3
  480. package/dist/ida/IdaInput.js +1 -7
  481. package/dist/ida/IdaMcpConnection.js +8 -4
  482. package/dist/ida/IdaOperationRunner.js +3 -3
  483. package/dist/ida/IdaProvider.js +8 -12
  484. package/dist/ida/IdaSessionClient.js +20 -18
  485. package/dist/ida/IdaWorkspace.js +12 -13
  486. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  487. package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
  488. package/dist/inspector/V8InspectorProvider.js +82 -36
  489. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  490. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  491. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  492. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  493. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  494. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  495. package/dist/main/shutdown.js +11 -3
  496. package/dist/main/startup.js +9 -2
  497. package/dist/main/transport.js +22 -2
  498. package/dist/main.js +11 -18
  499. package/dist/mcpDoctor.js +62 -2
  500. package/dist/native/AppleDispatchCoverage.js +47 -6
  501. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  502. package/dist/native/AppleDispatchMetadata.js +6 -3
  503. package/dist/native/AppleMachoFixups.js +48 -24
  504. package/dist/native/AppleMachoSelection.js +48 -22
  505. package/dist/native/AppleObjcCategories.js +6 -2
  506. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  507. package/dist/native/AppleObjcProperties.js +2 -1
  508. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  509. package/dist/native/AppleSwiftVtables.js +21 -15
  510. package/dist/native/CommandRunner.js +87 -88
  511. package/dist/native/LldbCallTracer.js +372 -103
  512. package/dist/native/LldbRetainedObservations.js +178 -0
  513. package/dist/native/NativeCallObservation.js +62 -3
  514. package/dist/native/NativeMacOSProvider.js +122 -31
  515. package/dist/native/NativeUiHelperRuntime.js +11 -2
  516. package/dist/native/NativeUiObservation.js +2 -2
  517. package/dist/native/SignatureTargetBinding.js +155 -0
  518. package/dist/native/parsers/lipo.js +71 -1
  519. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  520. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  521. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  522. package/dist/process/DarwinProcessRunTokenReader.js +23 -10
  523. package/dist/process/ExecFileOutput.js +108 -6
  524. package/dist/process/OwnedCommand.js +7 -2
  525. package/dist/process/PrivateRuntimeRoot.js +10 -5
  526. package/dist/process/ProcessOwnership.js +204 -57
  527. package/dist/process/ProcessOwnershipObservation.js +60 -9
  528. package/dist/process/ProviderProcess.js +39 -10
  529. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  530. package/dist/process/capture/ProcessCaptureError.js +15 -2
  531. package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
  532. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  533. package/dist/process/capture/ProcessHarness.js +21 -25
  534. package/dist/process/capture/ProcessNormalization.js +20 -2
  535. package/dist/process/capture/ProcessSampling.js +25 -2
  536. package/dist/process/capture/TerminalRenderer.js +14 -0
  537. package/dist/process/snapshotEnvironment.js +14 -0
  538. package/dist/server/EvidenceMcpServer.js +157 -0
  539. package/dist/server/createServer.js +61 -41
  540. package/dist/server/mcpClientMetadata.js +12 -5
  541. package/dist/server/promptCompletion.js +3 -8
  542. package/dist/server/registerAnalysisViewTool.js +15 -0
  543. package/dist/server/registerAndroidTools.js +2 -5
  544. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  545. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  546. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  547. package/dist/server/registerApplicationTools/coverage.js +1 -2
  548. package/dist/server/registerApplicationTools/helpers.js +1 -4
  549. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  550. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  551. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  552. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  553. package/dist/server/registerArtifactComparisonTool.js +13 -10
  554. package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
  555. package/dist/server/registerBrowserScenarioTool.js +3 -6
  556. package/dist/server/registerBrowserTools.js +13 -18
  557. package/dist/server/registerBundleComparisonTool.js +5 -7
  558. package/dist/server/registerCloseLifecycleTool.js +9 -20
  559. package/dist/server/registerElectronTools.js +10 -15
  560. package/dist/server/registerEnhancedTools.js +36 -77
  561. package/dist/server/registerEvidenceTools.js +3 -6
  562. package/dist/server/registerEvmTools.js +2 -5
  563. package/dist/server/registerFirmwareTools.js +2 -5
  564. package/dist/server/registerFunctionComparisonTool.js +15 -12
  565. package/dist/server/registerInvestigationTools.js +16 -17
  566. package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
  567. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
  568. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
  569. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
  570. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
  571. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
  572. package/dist/server/registerOfficialTools.js +4 -21
  573. package/dist/server/registerProcessComparisonTool.js +74 -48
  574. package/dist/server/registerRecordedCrashTools.js +2 -5
  575. package/dist/server/registerSessionRecordTools.js +19 -24
  576. package/dist/server/registerSessionStatusTool.js +19 -6
  577. package/dist/server/registerSessionTools.js +20 -18
  578. package/dist/server/registerWebModuleTool.js +2 -5
  579. package/dist/server/registerWebNetworkCaptureTool.js +2 -5
  580. package/dist/server/registerWebRuntimeTools.js +4 -9
  581. package/dist/server/registerWebScriptTool.js +2 -5
  582. package/dist/server/registerWebSourceLocationTool.js +2 -5
  583. package/dist/server/runDerivedOperation.js +15 -3
  584. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  585. package/dist/server/toolRegistrationOptions.js +2 -2
  586. package/dist/server/toolResult.js +75 -51
  587. package/dist/server/toolResultEncoding.js +34 -0
  588. package/dist/windows/WindowsNativeLoader.js +1 -0
  589. package/dist/windows/WindowsOwnedProcess.js +60 -15
  590. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  591. package/install.sh +1 -1
  592. package/native/windows/README.md +3 -1
  593. package/native/windows/build/manifest.json +2 -2
  594. package/native/windows/build/rea-windows-x64.node +0 -0
  595. package/package.json +44 -30
  596. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  597. package/scripts/electron-active-hook.cjs +241 -37
  598. package/scripts/rea.mjs +3 -6
  599. package/skills/reverse-engineer-anything/SKILL.md +12 -3
  600. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  601. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  602. package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
  603. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  604. package/dist/config.js +0 -1
  605. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  606. package/dist/contracts/process/processCaptureExample.js +0 -2
  607. package/dist/contracts/toolOutputSchemas.js +0 -2
  608. package/dist/ghidra/GhidraDefaults.js +0 -2
  609. package/dist/main/reload.js +0 -12
  610. package/dist/main/state.js +0 -3
  611. package/dist/server/sessionToolPolicies.js +0 -2
@@ -1,10 +1,18 @@
1
1
  import { z } from "zod";
2
2
  import { compatibleSlice, directoryOf, expandPrefix, joinPath, resolveTreePath, } from "./dyldPaths.js";
3
3
  import { digestSchema } from "../digests.js";
4
+ import { hasApplicableDyldOverrides, embeddedDyldOverrides, } from "./dyldEnvironment.js";
4
5
  import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, } from "./dylibResolutionFindings.js";
5
- /** Normalized path below the analyzed root: no `.`/`..` or empty segments. */
6
- const ROOT_RELATIVE_PATH = /^(?!\/)(?!(?:.*\/)?\.{1,2}(?:\/|$))(?!.*\/\/)(?!.*\/$)[^\\\0]+$/u;
7
- const rootRelativePathSchema = z.string().min(1).regex(ROOT_RELATIVE_PATH);
6
+ /**
7
+ * Normalized path below the analyzed root: nonempty segments joined by single
8
+ * `/`, none of them `.` or `..`, without backslash or NUL. Advertised schema
9
+ * patterns avoid look-around, which RE2 and Rust validators reject.
10
+ */
11
+ const ROOT_RELATIVE_PATH = /^(?:[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.\.[^\x2f\\\u0000]+)(?:\x2f(?:[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.\.[^\x2f\\\u0000]+))*$/u;
12
+ const rootRelativePathSchema = z
13
+ .string()
14
+ .min(1)
15
+ .regex(ROOT_RELATIVE_PATH, "Use a normalized path relative to the analyzed root, without a leading or trailing '/', '//', or '.' and '..' segments");
8
16
  /** Caller selection of process roots and one CPU slice. */
9
17
  export const dylibResolutionInputSchema = z.strictObject({
10
18
  roots: z.array(rootRelativePathSchema).min(1).optional(),
@@ -31,7 +39,20 @@ const dependencySchema = z.strictObject({
31
39
  /** Observed dylib-loading facts of one Mach-O slice. */
32
40
  export const machoSliceSchema = z.strictObject({
33
41
  architecture: z.string().min(1),
42
+ /** Physical identity observed in the thin header and, for FAT, its table. */
43
+ slice_offset: z.number().int().nonnegative(),
44
+ slice_size: z.number().int().positive(),
45
+ cpu_type: z.number().int().nonnegative(),
46
+ cpu_subtype: z.number().int().nonnegative(),
47
+ fat_cpu_type: z.number().int().nonnegative().nullable(),
48
+ fat_cpu_subtype: z.number().int().nonnegative().nullable(),
49
+ fat_alignment_exponent: z.number().int().nonnegative().nullable(),
34
50
  file_type: z.enum(["execute", "dylib", "bundle", "other"]),
51
+ file_type_code: z.number().int().nonnegative(),
52
+ /** Raw LC_BUILD_VERSION platform number; null means no such command was observed. */
53
+ platform: z.number().int().nonnegative().nullable(),
54
+ /** Every distinct build platform declared by LC_BUILD_VERSION/version-min commands. */
55
+ platforms: z.array(z.number().int().nonnegative()),
35
56
  install_name: z.string().nullable(),
36
57
  dependencies: z.array(dependencySchema),
37
58
  rpaths: z.array(z.string()),
@@ -56,6 +77,8 @@ const candidateSchema = z.strictObject({
56
77
  "malformed",
57
78
  "unsupported",
58
79
  "architecture-missing",
80
+ "not-loadable",
81
+ "platform-mismatch",
59
82
  "outside-target",
60
83
  "escapes-target",
61
84
  "undetermined",
@@ -168,13 +191,65 @@ const evaluateCandidate = async (template, context) => {
168
191
  if (lookup.kind !== "file")
169
192
  return { ...base, outcome: "absent", resolved_path: null };
170
193
  const facts = await imageFacts(context, lookup.path);
171
- const outcome = facts.status !== "parsed"
172
- ? facts.status
173
- : compatibleSlice(facts.slices, context.architecture) === undefined
174
- ? "architecture-missing"
175
- : "resolved";
194
+ let outcome;
195
+ if (facts.status !== "parsed")
196
+ outcome = facts.status;
197
+ else {
198
+ const slice = compatibleSlice(facts.slices, context.architecture);
199
+ if (slice === undefined)
200
+ outcome = "architecture-missing";
201
+ // Dependency commands require a dylib; generic dyld image loadability
202
+ // also admits main executables and bundles for different operations.
203
+ else if (slice.file_type_code !== 6)
204
+ outcome = "not-loadable";
205
+ else {
206
+ const platformResult = platformLoadability(context.platforms, slice.platforms, slice.file_type_code, context.architecture);
207
+ outcome =
208
+ platformResult === "compatible"
209
+ ? "resolved"
210
+ : platformResult === "incompatible"
211
+ ? "platform-mismatch"
212
+ : "undetermined";
213
+ }
214
+ }
176
215
  return { ...base, outcome, resolved_path: lookup.path };
177
216
  };
217
+ /** Apply dyld's documented cross-platform load cases and retain uncertain host cases. */
218
+ const platformLoadability = (processPlatforms, imagePlatforms, fileType, architecture) => {
219
+ if (processPlatforms.length === 0 || imagePlatforms.length === 0)
220
+ return "unknown";
221
+ const outcomes = processPlatforms.map((processPlatform) => imageLoadabilityForPlatform(processPlatform, imagePlatforms, fileType, architecture));
222
+ if (outcomes.every((outcome) => outcome === "compatible"))
223
+ return "compatible";
224
+ if (outcomes.every((outcome) => outcome === "incompatible"))
225
+ return "incompatible";
226
+ return "unknown";
227
+ };
228
+ const imageLoadabilityForPlatform = (processPlatform, imagePlatforms, fileType, architecture) => {
229
+ if (imagePlatforms.includes(processPlatform))
230
+ return "compatible";
231
+ // These are explicit dyld loadableIntoProcess cross-platform cases.
232
+ if (processPlatform === 6 && imagePlatforms.includes(1))
233
+ return "compatible"; // macOS dylibs in Mac Catalyst processes
234
+ if (processPlatform === 2 && imagePlatforms.includes(6))
235
+ return "compatible"; // Catalyst dylibs in iOS processes
236
+ if (processPlatform === 2 && imagePlatforms.includes(11))
237
+ return "compatible"; // visionOS dylibs in iOS processes
238
+ if (processPlatform === 7 && imagePlatforms.includes(12))
239
+ return "compatible"; // visionOS simulator dylibs in iOS simulator processes
240
+ if (processPlatform === 1 && fileType === 2 && imagePlatforms.includes(6))
241
+ return "compatible"; // Catalyst main executables run on macOS
242
+ // dyld's remaining exceptions depend on host architecture or a special path.
243
+ if ((processPlatform === 2 &&
244
+ imagePlatforms.includes(1) &&
245
+ architecture.startsWith("arm64")) ||
246
+ ([7, 8, 9].includes(processPlatform) && imagePlatforms.includes(1)))
247
+ return "unknown";
248
+ if (isKnownPlatform(processPlatform) && imagePlatforms.every(isKnownPlatform))
249
+ return "incompatible";
250
+ return "unknown";
251
+ };
252
+ const isKnownPlatform = (platform) => platform >= 1 && platform <= 12;
178
253
  const imageFacts = async (context, path) => {
179
254
  const known = context.images.get(path);
180
255
  if (known !== undefined)
@@ -222,7 +297,19 @@ const resolveDependency = async (dependency, loader, context) => {
222
297
  if (candidate.outcome === "resolved")
223
298
  break;
224
299
  }
225
- const searched = resolution(candidates);
300
+ const modeled = resolution(candidates);
301
+ const searchUnknown = loaded === undefined &&
302
+ hasApplicableDyldOverrides(context.searchOverrides, dependency.install_name, modeled.image !== null);
303
+ if (searchUnknown)
304
+ context.environmentRoots.add(context.root);
305
+ // Fallbacks cannot preempt a modeled hit, and framework paths do not
306
+ // override ordinary dylibs. Reuse inherits uncertainty from the first load.
307
+ const searched = searchUnknown
308
+ ? {
309
+ ...modeled,
310
+ status: modeled.image === null ? "undetermined" : "conditional",
311
+ }
312
+ : modeled;
226
313
  // Reusing an image that itself loads only conditionally is conditional too.
227
314
  const resolved = loaded !== undefined &&
228
315
  context.loaded.get(loaded)?.conditional === true &&
@@ -306,6 +393,7 @@ export const traceDylibLoading = async (view, request) => {
306
393
  const roots = [];
307
394
  const edges = [];
308
395
  const withoutArchitecture = [];
396
+ const environmentRoots = new Set();
309
397
  for (const root of request.roots) {
310
398
  const facts = await view.image(root);
311
399
  images.set(root, facts);
@@ -316,12 +404,23 @@ export const traceDylibLoading = async (view, request) => {
316
404
  if (slices.length === 0)
317
405
  withoutArchitecture.push(root);
318
406
  for (const slice of slices) {
407
+ const executable = slice.file_type === "execute" ? root : null;
408
+ // Only the main executable supplies the process's embedded environment.
409
+ const searchOverrides = executable === null
410
+ ? []
411
+ : embeddedDyldOverrides(slice.dyld_environment, slice.platforms);
412
+ // Inserted libraries introduce unexamined images even without dependencies.
413
+ if (searchOverrides.some(({ variable, value }) => variable === "DYLD_INSERT_LIBRARIES" && value !== ""))
414
+ environmentRoots.add(root);
319
415
  roots.push({ image: root, architecture: slice.architecture });
320
416
  edges.push(...(await traceProcess({
321
417
  view,
322
418
  root,
323
419
  architecture: slice.architecture,
324
- executable: slice.file_type === "execute" ? root : null,
420
+ searchOverrides,
421
+ environmentRoots,
422
+ platforms: slice.platforms,
423
+ executable,
325
424
  loaded: new Map(),
326
425
  byInstallName: new Map(),
327
426
  images,
@@ -347,18 +446,37 @@ export const traceDylibLoading = async (view, request) => {
347
446
  edges,
348
447
  findings: deriveFindings(edges, roots, images),
349
448
  coverage: {
350
- status: unparsed.length === 0 && withoutArchitecture.length === 0
449
+ status: unparsed.length === 0 &&
450
+ withoutArchitecture.length === 0 &&
451
+ environmentRoots.size === 0
351
452
  ? "complete"
352
453
  : "partial",
353
454
  unparsed_images: unparsed,
354
455
  roots_without_architecture: withoutArchitecture,
355
456
  },
356
- limitations: DYLIB_RESOLUTION_LIMITATIONS,
457
+ limitations: [
458
+ ...DYLIB_RESOLUTION_LIMITATIONS,
459
+ ...(environmentRoots.size === 0
460
+ ? []
461
+ : [
462
+ `Roots ${[...environmentRoots].join(", ")} request applicable image-selection inputs through LC_DYLD_ENVIRONMENT that are not modeled; affected dependencies or inserted images remain uncertain.`,
463
+ ]),
464
+ ],
357
465
  };
358
466
  };
359
467
  const withoutDependencies = (slice) => ({
360
468
  architecture: slice.architecture,
469
+ slice_offset: slice.slice_offset,
470
+ slice_size: slice.slice_size,
471
+ cpu_type: slice.cpu_type,
472
+ cpu_subtype: slice.cpu_subtype,
473
+ fat_cpu_type: slice.fat_cpu_type,
474
+ fat_cpu_subtype: slice.fat_cpu_subtype,
475
+ fat_alignment_exponent: slice.fat_alignment_exponent,
361
476
  file_type: slice.file_type,
477
+ file_type_code: slice.file_type_code,
478
+ platform: slice.platform,
479
+ platforms: slice.platforms,
362
480
  install_name: slice.install_name,
363
481
  rpaths: slice.rpaths,
364
482
  dyld_environment: slice.dyld_environment,
@@ -14,22 +14,24 @@ export const deriveFindings = (edges, roots, images) => {
14
14
  edge_index: index,
15
15
  image: edge.loader,
16
16
  basis: "derived",
17
- explanation: `dyld searches ${earlier.join(", ")} before ${edge.resolution.image ?? edge.install_name}. A Mach-O placed at an earlier path would load first unless code-signing library validation rejects it; library validation is not evaluated here (see inspect_signature).`,
17
+ explanation: `The modeled dyld search checks ${earlier.join(", ")} before ${edge.resolution.image ?? edge.install_name}. A compatible Mach-O placed at an earlier modeled path could take precedence over that fallback, subject to unmodeled search inputs and code-signing library validation; library validation is not evaluated here (see inspect_signature).${edge.loader_conditional ? " This loader loads only conditionally; if it never loads, this search never occurs." : ""}${edge.resolution.status === "conditional" ? " Unmodeled environment overrides or earlier unknown candidates may take precedence; placing an image at this rpath does not establish which image dyld will load." : ""}`,
18
18
  });
19
19
  });
20
20
  for (const { image, architecture } of roots) {
21
21
  const facts = images.get(image);
22
- const environment = facts?.status === "parsed"
23
- ? (facts.slices.find((slice) => slice.architecture === architecture)
24
- ?.dyld_environment ?? [])
25
- : [];
22
+ const slice = facts?.status === "parsed"
23
+ ? facts.slices.find((candidate) => candidate.architecture === architecture)
24
+ : undefined;
25
+ const environment = slice?.dyld_environment ?? [];
26
26
  if (environment.length > 0)
27
27
  findings.push({
28
28
  kind: "dyld-environment-present",
29
29
  edge_index: null,
30
30
  image,
31
31
  basis: "derived",
32
- explanation: `${image} (${architecture}) sets dyld environment variables through LC_DYLD_ENVIRONMENT (${environment.join(", ")}); search paths they add are not modeled.`,
32
+ explanation: slice?.file_type === "execute"
33
+ ? `${image} (${architecture}) sets dyld environment variables through LC_DYLD_ENVIRONMENT (${environment.join(", ")}); any image-selection overrides they request are not modeled. Diagnostic settings alone do not alter resolution.`
34
+ : `${image} (${architecture}) contains LC_DYLD_ENVIRONMENT (${environment.join(", ")}). Dyld reads these commands only from the main executable; entries in this non-executable root are observations and do not alter resolution.`,
33
35
  });
34
36
  }
35
37
  return findings;
@@ -60,7 +62,7 @@ const unresolvedFinding = (edge, index) => {
60
62
  : {
61
63
  ...base,
62
64
  kind: "required-load-unresolved",
63
- explanation: `${missing}${when}dyld would fail to launch ${edge.root} (${edge.architecture}) unless the image is supplied elsewhere.`,
65
+ explanation: `${missing}${when}dyld would fail to load this required dependency for ${edge.root} (${edge.architecture}) unless the image is supplied elsewhere.`,
64
66
  };
65
67
  };
66
68
  export const DYLIB_RESOLUTION_LIMITATIONS = [
@@ -1,7 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { firstString, parseInterfaceBuilderRecords, record, } from "./interfaceBuilderKeyedArchive.js";
3
3
  import { nativeInvestigationEdgeSchema, nativeInvestigationGraphSchema, nativeInvestigationNodeSchema, nativeInvestigationTraceLimitsSchema, } from "../native/nativeInvestigationGraph.js";
4
- export { parseInterfaceBuilderRecords } from "./interfaceBuilderKeyedArchive.js";
5
4
  /** One compiled Interface Builder document projected from ibtool output. */
6
5
  export const interfaceBuilderDocumentSchema = z.strictObject({
7
6
  relative_path: z.string().min(1),
@@ -28,6 +27,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
28
27
  let omittedObjects = 0;
29
28
  let omittedConnections = 0;
30
29
  let omittedGraphNodes = 0;
30
+ let omittedHierarchyReferences = 0;
31
31
  for (const document of input.documents.slice(0, input.limits.max_documents)) {
32
32
  const parsed = parseInterfaceBuilderRecords(document.raw);
33
33
  const prefix = `ib:${document.relativePath}:`;
@@ -276,6 +276,8 @@ export const buildInterfaceBuilderAnalysis = (input) => {
276
276
  }
277
277
  }
278
278
  const objectsTruncated = parsed.omittedObjects > 0 || parsed.objects.length > documentObjectCount;
279
+ const parserOmittedHierarchyReferences = parsed.omittedHierarchyReferences;
280
+ omittedHierarchyReferences += parserOmittedHierarchyReferences;
279
281
  const parserOmittedConnections = parsed.omittedConnections;
280
282
  const connectionsTruncated = parserOmittedConnections > 0 ||
281
283
  parsed.connections.length > input.limits.max_connections;
@@ -291,7 +293,9 @@ export const buildInterfaceBuilderAnalysis = (input) => {
291
293
  document_kind: document.documentKind,
292
294
  object_count: parsed.objectCount,
293
295
  connection_count: parsed.connections.length + parserOmittedConnections,
294
- hierarchy_complete: parsed.hierarchy.length > 0 && !truncated,
296
+ hierarchy_complete: parsed.hierarchy.length > 0 &&
297
+ !truncated &&
298
+ parserOmittedHierarchyReferences === 0,
295
299
  });
296
300
  coverage.push({
297
301
  facet: `objects:${document.relativePath}`,
@@ -314,18 +318,22 @@ export const buildInterfaceBuilderAnalysis = (input) => {
314
318
  parserOmittedConnections,
315
319
  }, {
316
320
  facet: `hierarchy:${document.relativePath}`,
317
- status: parsed.hierarchy.length === 0
318
- ? "unsupported"
319
- : hierarchyTruncated || documentOmittedHierarchyEdges > 0
320
- ? "partial"
321
- : "complete",
322
- reason: parsed.hierarchy.length === 0
323
- ? "archive_hierarchy_not_decoded"
324
- : hierarchyTruncated || documentOmittedHierarchyEdges > 0
325
- ? "graph_limit_reached"
326
- : null,
321
+ status: parserOmittedHierarchyReferences > 0
322
+ ? "partial"
323
+ : parsed.hierarchy.length === 0
324
+ ? "unsupported"
325
+ : hierarchyTruncated || documentOmittedHierarchyEdges > 0
326
+ ? "partial"
327
+ : "complete",
328
+ reason: parserOmittedHierarchyReferences > 0
329
+ ? "archive_hierarchy_references_missing"
330
+ : parsed.hierarchy.length === 0
331
+ ? "archive_hierarchy_not_decoded"
332
+ : hierarchyTruncated || documentOmittedHierarchyEdges > 0
333
+ ? "graph_limit_reached"
334
+ : null,
327
335
  examined: hierarchyCount,
328
- omitted: documentOmittedHierarchyEdges,
336
+ omitted: documentOmittedHierarchyEdges + parserOmittedHierarchyReferences,
329
337
  }, {
330
338
  facet: `classes:${document.relativePath}`,
331
339
  status: Object.keys(parsed.classes).length > 0 ? "complete" : "unsupported",
@@ -367,7 +375,10 @@ export const buildInterfaceBuilderAnalysis = (input) => {
367
375
  nodes: [...nodes.values()],
368
376
  edges,
369
377
  coverage,
370
- truncated: truncated || omittedObjects > 0 || omittedConnections > 0,
378
+ truncated: truncated ||
379
+ omittedObjects > 0 ||
380
+ omittedConnections > 0 ||
381
+ omittedHierarchyReferences > 0,
371
382
  },
372
383
  limitations: [
373
384
  "The graph reflects recognized Interface Builder archive fields and connections; omitted private or unrecognized archive fields remain unknown.",
@@ -82,6 +82,7 @@ export const parseInterfaceBuilderRecords = (value) => {
82
82
  objectCount: objectEntries.length,
83
83
  omittedObjects: Math.max(0, objectEntries.length - 20_000),
84
84
  omittedConnections,
85
+ omittedHierarchyReferences: 0,
85
86
  };
86
87
  };
87
88
  /**
@@ -164,6 +165,7 @@ const keyedArchiveTable = (objectTable) => {
164
165
  return output;
165
166
  };
166
167
  const hierarchy = (start) => {
168
+ let omittedReferences = 0;
167
169
  const visited = new Set();
168
170
  const root = [];
169
171
  const pending = [
@@ -190,10 +192,17 @@ const keyedArchiveTable = (objectTable) => {
190
192
  const { value, output } = entry;
191
193
  const uid = archiveUid(value);
192
194
  if (uid !== undefined) {
195
+ // UID0 is archived nil, not a missing hierarchy object.
196
+ if (uid === 0)
197
+ continue;
198
+ const target = objectTable[uid];
199
+ if (target === undefined) {
200
+ omittedReferences += 1;
201
+ continue;
202
+ }
193
203
  if (visited.has(uid))
194
204
  continue;
195
205
  visited.add(uid);
196
- const target = objectTable[uid];
197
206
  if (Array.isArray(target)) {
198
207
  for (let index = target.length - 1; index >= 0; index -= 1) {
199
208
  const child = target[index];
@@ -229,7 +238,7 @@ const keyedArchiveTable = (objectTable) => {
229
238
  appendNode(record(value), undefined, output);
230
239
  }
231
240
  }
232
- return root;
241
+ return { items: root, omittedReferences };
233
242
  };
234
243
  const archivedArrayClass = (classReference) => {
235
244
  const uid = archiveUid(classReference);
@@ -317,11 +326,12 @@ const parseKeyedArchive = (root) => {
317
326
  return {
318
327
  objects,
319
328
  connections,
320
- hierarchy,
329
+ hierarchy: hierarchy.items,
321
330
  classes,
322
331
  objectCount,
323
332
  omittedObjects: Math.max(0, objectCount - 20_000),
324
333
  omittedConnections,
334
+ omittedHierarchyReferences: hierarchy.omittedReferences,
325
335
  };
326
336
  };
327
337
  /** Coerce unknown values to a string-keyed record; non-objects become `{}`. */
@@ -1,5 +1,20 @@
1
1
  import { z } from "zod";
2
+ import { AnalysisInputError } from "../analysisErrorCore.js";
2
3
  import { jsonValueSchema } from "../jsonValue.js";
4
+ /**
5
+ * The selected file is intact but is another kind of file, so another tool
6
+ * applies. A malformed NSKeyedArchiver archive is not this error.
7
+ */
8
+ export class KeyedArchiveKindError extends TypeError {
9
+ kind;
10
+ name = "KeyedArchiveKindError";
11
+ constructor(message,
12
+ /** What the selected file is instead. */
13
+ kind) {
14
+ super(message);
15
+ this.kind = kind;
16
+ }
17
+ }
3
18
  /** Select one archive within the active bundle and optionally one named root. */
4
19
  export const keyedArchiveInputSchema = z.strictObject({
5
20
  path: z.string().min(1).default("."),
@@ -59,11 +74,21 @@ const uid = (value) => {
59
74
  const marker = Object.hasOwn(object, "UID") ? object.UID : object["CF$UID"];
60
75
  return typeof marker === "number" ? marker : undefined;
61
76
  };
77
+ const archiverMismatch = (archive) => {
78
+ if (archive === undefined)
79
+ return "its root is not a dictionary";
80
+ if (!Object.hasOwn(archive, "$archiver"))
81
+ return "it has no $archiver key";
82
+ return typeof archive.$archiver === "string"
83
+ ? `its $archiver is ${JSON.stringify(archive.$archiver)}`
84
+ : "its $archiver is not a string";
85
+ };
62
86
  /** Interpret serialized Foundation references without instantiating archive classes. */
63
87
  export const projectKeyedArchive = (value, selection) => {
64
88
  const archive = record(jsonValueSchema.parse(value));
65
- if (archive?.$archiver !== "NSKeyedArchiver" ||
66
- !Array.isArray(archive.$objects))
89
+ if (archive?.$archiver !== "NSKeyedArchiver")
90
+ throw new KeyedArchiveKindError(`Selected property list is not an NSKeyedArchiver archive: ${archiverMismatch(archive)}`, "property-list");
91
+ if (!Array.isArray(archive.$objects))
67
92
  throw new TypeError("Expected NSKeyedArchiver with an $objects array");
68
93
  const table = archive.$objects;
69
94
  if (table.length > 200_000)
@@ -72,7 +97,14 @@ export const projectKeyedArchive = (value, selection) => {
72
97
  if (top === undefined || Object.keys(top).length === 0)
73
98
  throw new TypeError("Keyed archive has no $top roots");
74
99
  if (selection.root !== undefined && !Object.hasOwn(top, selection.root))
75
- throw new TypeError(`Archive root does not exist: ${selection.root}`);
100
+ throw new AnalysisInputError("inspect_keyed_archive", undefined, [
101
+ {
102
+ path: ["root"],
103
+ reason: "invalid_value",
104
+ message: `Archive root does not exist: ${selection.root}. Select one of the archive's $top roots or omit root.`,
105
+ expected: Object.keys(top),
106
+ },
107
+ ]);
76
108
  const roots = selection.root === undefined
77
109
  ? top
78
110
  : { [selection.root]: top[selection.root] ?? null };
@@ -0,0 +1,54 @@
1
+ /** Decode FAT table entries once so artifact and native readers share identity facts. */
2
+ export const readFatSliceDeclarations = (tableBytes, options) => {
3
+ const { count, wide, littleEndian } = options;
4
+ const entrySize = wide ? 32 : 20;
5
+ if (tableBytes.byteLength < count * entrySize)
6
+ return { status: "malformed", reason: "FAT table is truncated" };
7
+ const view = new DataView(tableBytes.buffer, tableBytes.byteOffset, tableBytes.byteLength);
8
+ const slices = [];
9
+ for (let index = 0; index < count; index++) {
10
+ const base = index * entrySize;
11
+ const offset = wide
12
+ ? safeNumber(view.getBigUint64(base + 8, littleEndian))
13
+ : view.getUint32(base + 8, littleEndian);
14
+ const size = wide
15
+ ? safeNumber(view.getBigUint64(base + 16, littleEndian))
16
+ : view.getUint32(base + 12, littleEndian);
17
+ if (offset === null || size === null)
18
+ return {
19
+ status: "malformed",
20
+ reason: "FAT offset or size exceeds the safe range",
21
+ };
22
+ slices.push({
23
+ index,
24
+ offset,
25
+ size,
26
+ alignmentExponent: view.getUint32(base + (wide ? 24 : 16), littleEndian),
27
+ cpuType: view.getUint32(base, littleEndian),
28
+ cpuSubtype: view.getUint32(base + 4, littleEndian),
29
+ });
30
+ }
31
+ return { status: "parsed", slices };
32
+ };
33
+ /** Validate byte-range and table/header identity facts shared by Mach-O readers. */
34
+ export const validateFatSlice = (declaration, containerSize, tableEnd, embedded) => {
35
+ const { index, offset, size, alignmentExponent, cpuType, cpuSubtype } = declaration;
36
+ if (!Number.isSafeInteger(offset) ||
37
+ !Number.isSafeInteger(size) ||
38
+ size <= 0 ||
39
+ offset < tableEnd)
40
+ return `FAT architecture ${index} has an invalid slice range`;
41
+ if (offset > containerSize || size > containerSize - offset)
42
+ return `FAT architecture ${index} slice range extends beyond the file`;
43
+ if (!Number.isInteger(alignmentExponent) ||
44
+ alignmentExponent < 0 ||
45
+ alignmentExponent > 52)
46
+ return `FAT architecture ${index} alignment exponent ${alignmentExponent} is unsupported`;
47
+ if (offset % 2 ** alignmentExponent !== 0)
48
+ return `FAT architecture ${index} offset is not aligned to 2^${alignmentExponent}`;
49
+ if (embedded !== undefined &&
50
+ (embedded.cpuType !== cpuType || embedded.cpuSubtype !== cpuSubtype))
51
+ return `FAT architecture ${index} CPU type/subtype disagrees with its Mach-O header`;
52
+ return null;
53
+ };
54
+ const safeNumber = (value) => value > BigInt(Number.MAX_SAFE_INTEGER) ? null : Number(value);
@@ -0,0 +1,76 @@
1
+ /** Preserve unambiguous exact integers; disclose rounded or unclassified numbers. */
2
+ export const createPlistNumberProjection = (literals) => {
3
+ let exactIntegerCount = 0;
4
+ let ambiguousNumberCount = 0;
5
+ const mapNumber = (item) => {
6
+ if (Number.isSafeInteger(item) || !Number.isInteger(item))
7
+ return item;
8
+ if (literals.incomplete) {
9
+ ambiguousNumberCount += 1;
10
+ return item;
11
+ }
12
+ const decimals = literals.integers.get(item);
13
+ if (decimals === undefined) {
14
+ if (!literals.reals.has(item))
15
+ ambiguousNumberCount += 1;
16
+ return item;
17
+ }
18
+ const [decimal] = decimals;
19
+ if (decimals.size !== 1 ||
20
+ decimal === undefined ||
21
+ literals.reals.has(item)) {
22
+ ambiguousNumberCount += 1;
23
+ return item;
24
+ }
25
+ exactIntegerCount += 1;
26
+ return { $plist_type: "integer", decimal };
27
+ };
28
+ const map = (item) => {
29
+ if (typeof item === "number")
30
+ return mapNumber(item);
31
+ if (Array.isArray(item))
32
+ return item.map(map);
33
+ if (item !== null && typeof item === "object") {
34
+ const keys = Object.keys(item);
35
+ const marker = item[keys[0] ?? ""];
36
+ const reference = keys.length === 1 &&
37
+ (keys[0] === "UID" || keys[0] === "CF$UID") &&
38
+ typeof marker === "number";
39
+ if (reference) {
40
+ // Keep malformed numeric reference markers recognizable by the graph reader.
41
+ if (typeof marker === "number" &&
42
+ !Number.isSafeInteger(marker) &&
43
+ (literals.integers.has(marker) || !literals.reals.has(marker)))
44
+ ambiguousNumberCount += 1;
45
+ return item;
46
+ }
47
+ return Object.fromEntries(Object.entries(item).map(([key, child]) => [key, map(child)]));
48
+ }
49
+ return item;
50
+ };
51
+ return {
52
+ project: map,
53
+ limitations: () => [
54
+ ...(literals.incomplete
55
+ ? [
56
+ "Original archive number metadata could not be completely observed; decoded numbers may lose integer precision and exact integer/real association is unavailable.",
57
+ ]
58
+ : []),
59
+ ...(literals.unsafeIntegerLiterals === 0
60
+ ? []
61
+ : [
62
+ `${String(literals.unsafeIntegerLiterals)} observed integer literal(s) in the original archive exceed the exact range of a JSON number. Decoded numbers may lose integer precision unless represented as { "$plist_type": "integer", "decimal": "<exact digits>" }; the original archive bytes retain those literals.`,
63
+ ]),
64
+ ...(exactIntegerCount === 0
65
+ ? []
66
+ : [
67
+ `${String(exactIntegerCount)} unambiguous integer value(s) are reported with exact decimal text as { "$plist_type": "integer", "decimal": "<exact digits>" }.`,
68
+ ]),
69
+ ...(ambiguousNumberCount === 0
70
+ ? []
71
+ : [
72
+ `${String(ambiguousNumberCount)} number(s) beyond the exact integer range remain as decoded because their source integer/real type or reference marker cannot be associated unambiguously; integer precision loss remains possible.`,
73
+ ]),
74
+ ],
75
+ };
76
+ };
@@ -1,3 +1,4 @@
1
+ import { compareCodePoints } from "./canonicalOrdering.js";
1
2
  import { z } from "zod";
2
3
  import {} from "./artifactGraph.js";
3
4
  import { evidenceSchema } from "./evidence.js";
@@ -111,7 +112,7 @@ export const compareArtifacts = (leftEvidence, rightEvidence) => {
111
112
  right_manifest_id: right.inventory.manifest.manifest_id,
112
113
  summary,
113
114
  changes,
114
- limitations: [...new Set(limitations)].sort((a, b) => a.localeCompare(b)),
115
+ limitations: [...new Set(limitations)].sort(compareCodePoints),
115
116
  });
116
117
  };
117
118
  const compareOccurrences = (left, right, evidenceLinks, complete) => {
@@ -123,7 +124,7 @@ const compareOccurrences = (left, right, evidenceLinks, complete) => {
123
124
  const rightRelations = relationsByPath(right);
124
125
  const paths = [
125
126
  ...new Set([...leftByPath.keys(), ...rightByPath.keys()]),
126
- ].sort((a, b) => a.localeCompare(b, "en"));
127
+ ].sort(compareCodePoints);
127
128
  const output = [];
128
129
  for (const path of paths) {
129
130
  const leftOccurrence = leftByPath.get(path);
@@ -208,8 +209,17 @@ const changedDimensions = (input) => {
208
209
  return ["availability"];
209
210
  const checks = [
210
211
  ["content", left.sha256 !== right.sha256],
211
- ["kind", left.kind !== right.kind],
212
- ["format", left.format !== right.format],
212
+ [
213
+ "kind",
214
+ input.leftOccurrence?.artifact_kind !==
215
+ input.rightOccurrence?.artifact_kind,
216
+ ],
217
+ [
218
+ "format",
219
+ left.format !== right.format ||
220
+ input.leftOccurrence?.artifact_format !==
221
+ input.rightOccurrence?.artifact_format,
222
+ ],
213
223
  ["size", left.size !== right.size],
214
224
  [
215
225
  "executable",
@@ -228,7 +238,6 @@ const changedDimensions = (input) => {
228
238
  };
229
239
  const metadataChanged = (input, left, right) => left.media_type !== right.media_type ||
230
240
  left.architecture !== right.architecture ||
231
- left.executable !== right.executable ||
232
241
  left.content_state !== right.content_state ||
233
242
  input.leftOccurrence?.entry_kind !== input.rightOccurrence?.entry_kind ||
234
243
  input.leftOccurrence?.encrypted !== input.rightOccurrence?.encrypted ||
@@ -262,7 +271,7 @@ const relationsByPath = (inventory) => {
262
271
  values.push(projection);
263
272
  }
264
273
  for (const values of output.values())
265
- values.sort((left, right) => canonicalJson(left).localeCompare(canonicalJson(right)));
274
+ values.sort((left, right) => compareCodePoints(canonicalJson(left), canonicalJson(right)));
266
275
  return output;
267
276
  };
268
277
  const summarize = (left, right, changes, covered) => {