rea-agents 6.2.0 → 6.4.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 (636) hide show
  1. package/README.md +24 -23
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -1,7 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import canonicalize from "canonicalize";
3
3
  import { z } from "zod";
4
- import { appleBundleSchema, appleComponentSchema, applicationRoots, detectBundles, isMachOFormat, isSidecar, isWithin, platformsOf, } from "./appleBundleAnatomy.js";
4
+ import { anatomyNameIs, anatomyTailMatches, appleBundleSchema, appleComponentSchema, applicationRoots, detectBundles, isMachOFormat, isSidecar, isWithin, platformsOf, } from "./appleBundleAnatomy.js";
5
+ import { isSwiftRuntimeLibrary, nativeRuntimeConvention, } from "../nativeConvention.js";
5
6
  import { parseArtifactInventoryEvidence } from "../artifactInventoryEvidence.js";
6
7
  import { evidenceSchema } from "../evidence.js";
7
8
  import { digestSchema } from "../digests.js";
@@ -166,48 +167,61 @@ const appleRootFormat = (format) => {
166
167
  };
167
168
  const classifyComponents = (entries, all, roots) => {
168
169
  const withinApp = (path) => roots.some((root) => isWithin(path, root));
169
- const anatomy = (pattern) => entries.flatMap(({ path, kind, component }) => kind === "file" &&
170
+ const matching = (predicate) => entries.flatMap(({ path, kind, component }) => kind === "file" &&
170
171
  component !== undefined &&
171
172
  !isSidecar(path) &&
172
173
  withinApp(path) &&
173
- pattern.test(path)
174
+ predicate(path)
174
175
  ? [component]
175
176
  : []);
177
+ const lastSegment = (path) => path.split("/").at(-1) ?? "";
176
178
  return {
177
- bundle_metadata: all.filter(({ path }) => /(?:^|\/)Info\.plist$/u.test(path)),
179
+ bundle_metadata: all.filter(({ path }) => anatomyNameIs(lastSegment(path), "Info.plist")),
178
180
  executables: all.filter(({ path, format }) => withinApp(path) && isMachOFormat(format)),
179
181
  frameworks: all.filter(({ path }) => /\.framework\//u.test(path)),
180
182
  native_libraries: all.filter(({ path }) => /\.(?:dylib|so)$/iu.test(path)),
181
183
  javascript: all.filter(({ format }) => format === "javascript-bundle"),
182
- signing: all.filter(({ path }) => /(?:^|\/)(?:embedded\.(?:mobileprovision|provisionprofile)|_CodeSignature\/CodeResources)$/u.test(path)),
183
- privileged_helpers: anatomy(/(?:^|\/)Contents\/Library\/LaunchServices\/[^/]+$/u),
184
- launchd_plists: anatomy(/(?:^|\/)Contents\/Library\/Launch(?:Agents|Daemons)\/[^/]+\.plist$/u).map((component) => ({
184
+ signing: all.filter(({ path }) => anatomyTailMatches(path, ["_CodeSignature", "CodeResources"]) ||
185
+ anatomyNameIs(lastSegment(path), "embedded.mobileprovision") ||
186
+ anatomyNameIs(lastSegment(path), "embedded.provisionprofile")),
187
+ privileged_helpers: matching((path) => anatomyTailMatches(path, ["Contents", "Library", "LaunchServices", "*"])),
188
+ launchd_plists: matching((path) => path.endsWith(".plist") &&
189
+ (anatomyTailMatches(path, [
190
+ "Contents",
191
+ "Library",
192
+ "LaunchAgents",
193
+ "*",
194
+ ]) ||
195
+ anatomyTailMatches(path, [
196
+ "Contents",
197
+ "Library",
198
+ "LaunchDaemons",
199
+ "*",
200
+ ]))).map((component) => ({
185
201
  ...component,
186
- domain: component.path.includes("/LaunchDaemons/")
202
+ domain: component.path
203
+ .split("/")
204
+ .some((segment) => anatomyNameIs(segment, "LaunchDaemons"))
187
205
  ? "daemon"
188
206
  : "agent",
189
207
  })),
190
- helpers: anatomy(/(?:^|\/)Contents\/Helpers\/[^/]+$/u),
208
+ helpers: matching((path) => anatomyTailMatches(path, ["Contents", "Helpers", "*"])),
191
209
  };
192
210
  };
193
211
  const deduplicateComponents = (values) => [...new Map(values.map((value) => [value.path, value])).values()].sort((left, right) => compare(left.path, right.path));
194
212
  const identifyRuntimeFamilies = (all) => {
195
- const paths = all.map(({ path }) => path.toLowerCase());
196
213
  const families = new Set();
197
214
  if (all.some(({ format }) => ["mach-o", "mach-o-universal"].includes(format)))
198
215
  families.add("native");
199
- if (paths.some((path) => /\.(?:dylib|framework\/[^/]+)$/u.test(path)))
216
+ if (all.some(({ path }) => isSwiftRuntimeLibrary(path)))
200
217
  families.add("swift-objective-c");
201
218
  if (all.some(({ format }) => format === "javascript-bundle"))
202
219
  families.add("javascript");
203
- if (paths.some((path) => path.includes("reactnative") ||
204
- path.includes("react.framework") ||
205
- path.includes("hermes")))
206
- families.add("react-native");
207
- if (paths.some((path) => path.includes("flutter.framework") || path.includes("app.framework")))
208
- families.add("flutter");
209
- if (paths.some((path) => path.includes("unityframework.framework")))
210
- families.add("unity");
220
+ for (const { path } of all) {
221
+ const convention = nativeRuntimeConvention(path);
222
+ if (convention !== null)
223
+ families.add(convention);
224
+ }
211
225
  return [...families].sort(compare);
212
226
  };
213
227
  /** Pair scripts and native code within matching application-root groups. */
@@ -243,12 +257,12 @@ const identifyBridgeCandidates = (scripts, native, roots) => {
243
257
  });
244
258
  };
245
259
  const bridgeBasis = (path) => {
246
- const lower = path.toLowerCase();
247
- if (lower.includes("react"))
260
+ const convention = nativeRuntimeConvention(path);
261
+ if (convention === "react-native")
248
262
  return "react-native-convention";
249
- if (lower.includes("flutter") || lower.includes("app.framework"))
263
+ if (convention === "flutter")
250
264
  return "flutter-convention";
251
- if (lower.includes("unity"))
265
+ if (convention === "unity")
252
266
  return "unity-convention";
253
267
  return "javascript-and-native-content";
254
268
  };
@@ -293,7 +307,10 @@ const projectionLimitations = (facts) => [
293
307
  : []),
294
308
  "Bundle roles follow path conventions. Read each info_plist_path with inspect_plist for CFBundleExecutable, identifiers, and declared services.",
295
309
  "Bundle identifiers and signing claims require dedicated plist and CMS parsing; this projection reports only exact paths and hashes.",
310
+ "Runtime families are inferred from inventory formats and bounded framework path conventions, not observed runtime loading.",
311
+ "Generic framework and dylib paths do not establish Swift or Objective-C; this inventory projection does not decode language metadata.",
296
312
  "Bridge candidates are path-based hypotheses, not observed runtime calls.",
313
+ "A bridge basis is inferred from the native path and is repeated for every managed component.",
297
314
  ];
298
315
  const compare = (left, right) => left < right ? -1 : left > right ? 1 : 0;
299
316
  const digest = (value) => {
@@ -42,6 +42,42 @@ export const isSidecar = (path) => {
42
42
  return (segments.includes("__MACOSX") || (segments.at(-1) ?? "").startsWith("._"));
43
43
  };
44
44
  export const isWithin = (path, root) => root === "." || path === root || path.startsWith(`${root}/`);
45
+ /**
46
+ * English (en-US) case fold used only for Apple's fixed anatomy vocabulary.
47
+ * Reported paths keep the archive spelling. Inventory identity stays case-sensitive.
48
+ */
49
+ export const anatomyNameIs = (actual, expected) => actual.toLocaleLowerCase("en-US") === expected.toLocaleLowerCase("en-US");
50
+ /** Directory entry that folds to one vocabulary word. The exact spelling wins. */
51
+ export const anatomyChild = (names, expected) => {
52
+ if (names === undefined)
53
+ return null;
54
+ let exact;
55
+ let folded;
56
+ for (const name of names) {
57
+ if (name === expected)
58
+ exact = name;
59
+ else if (anatomyNameIs(name, expected) &&
60
+ (folded === undefined || compare(name, folded) < 0))
61
+ folded = name;
62
+ }
63
+ return exact ?? folded ?? null;
64
+ };
65
+ /**
66
+ * Whether `path`'s tail matches anatomy vocabulary. `*` matches one segment
67
+ * that is not itself a vocabulary comparison.
68
+ */
69
+ export const anatomyTailMatches = (path, expected) => {
70
+ const actual = path.split("/");
71
+ if (actual.length < expected.length)
72
+ return false;
73
+ const tail = actual.slice(-expected.length);
74
+ return expected.every((name, index) => {
75
+ const segment = tail[index];
76
+ if (segment === undefined || segment.length === 0)
77
+ return false;
78
+ return name === "*" || anatomyNameIs(segment, name);
79
+ });
80
+ };
45
81
  /**
46
82
  * Outermost iOS (`Payload/X.app`) and macOS (`X.app/Contents/…`) applications.
47
83
  * An inventoried `.app` directory is its own root, `.`.
@@ -55,13 +91,16 @@ export const applicationRoots = (entries, subject) => {
55
91
  for (const { path } of entries) {
56
92
  if (isSidecar(path))
57
93
  continue;
58
- const ios = /^(Payload\/[^/]+\.app)(?:\/|$)/u.exec(path);
59
- if (ios?.[1] !== undefined) {
60
- found.add(ios[1]);
94
+ const segments = path.split("/");
95
+ const app = segments[1];
96
+ if (anatomyNameIs(segments[0] ?? "", "Payload") &&
97
+ app !== undefined &&
98
+ /\.app$/iu.test(app)) {
99
+ found.add(`${segments[0]}/${app}`);
61
100
  continue;
62
101
  }
63
- const segments = path.split("/");
64
- const index = segments.findIndex((segment, position) => /\.app$/iu.test(segment) && segments[position + 1] === "Contents");
102
+ const index = segments.findIndex((segment, position) => /\.app$/iu.test(segment) &&
103
+ anatomyNameIs(segments[position + 1] ?? "", "Contents"));
65
104
  if (index >= 0)
66
105
  found.add(segments.slice(0, index + 1).join("/"));
67
106
  }
@@ -142,9 +181,9 @@ const enclosingBundle = (path, bundles) => {
142
181
  };
143
182
  const bundleLayout = (bundle, tree) => {
144
183
  const names = tree.children.get(directoryOf(bundle));
145
- if (names?.has("Contents") === true)
184
+ if (anatomyChild(names, "Contents") !== null)
146
185
  return "macos-deep";
147
- if (names?.has("Versions") === true)
186
+ if (anatomyChild(names, "Versions") !== null)
148
187
  return "versioned-framework";
149
188
  return "shallow";
150
189
  };
@@ -163,15 +202,18 @@ const bundleRole = (bundle) => {
163
202
  if (name.endsWith(".dext"))
164
203
  return "driver-extension";
165
204
  if (name.endsWith(".bundle")) {
166
- if (container === "PlugIns")
205
+ if (anatomyNameIs(container ?? "", "PlugIns"))
167
206
  return "plug-in";
168
- return container === "Resources" ? "resource-bundle" : "bundle";
207
+ return anatomyNameIs(container ?? "", "Resources")
208
+ ? "resource-bundle"
209
+ : "bundle";
169
210
  }
170
211
  if (!name.endsWith(".app"))
171
212
  return "plug-in";
172
- if (container === "LoginItems" && segments.at(-3) === "Library")
213
+ if (anatomyNameIs(container ?? "", "LoginItems") &&
214
+ anatomyNameIs(segments.at(-3) ?? "", "Library"))
173
215
  return "login-item";
174
- if (container === "Helpers")
216
+ if (anatomyNameIs(container ?? "", "Helpers"))
175
217
  return "helper-application";
176
218
  return "nested-application";
177
219
  };
@@ -183,42 +225,67 @@ const directFiles = (directory, tree) => [...(tree.children.get(directory) ?? []
183
225
  /** Content directories; `Versions/Current` is a symlink outside the inventory. */
184
226
  const contentDirectories = (bundle, layout, tree) => {
185
227
  const directory = directoryOf(bundle);
186
- if (layout === "macos-deep")
187
- return [joinPath(directory, "Contents")];
228
+ if (layout === "macos-deep") {
229
+ const contents = namedChild(tree, directory, "Contents");
230
+ return contents === null ? [] : [contents];
231
+ }
188
232
  if (layout === "shallow")
189
233
  return [directory];
190
- const versions = joinPath(directory, "Versions");
234
+ const versions = namedChild(tree, directory, "Versions");
235
+ if (versions === null)
236
+ return [];
191
237
  // Only real version directories count: Current is a symlink, and files
192
238
  // such as .DS_Store are not versions.
193
239
  return [...(tree.children.get(versions) ?? [])]
194
- .filter((version) => version !== "Current")
240
+ .filter((version) => !anatomyNameIs(version, "Current"))
195
241
  .map((version) => joinPath(versions, version))
196
242
  .filter((version) => tree.directories.has(version))
197
243
  .sort(compare);
198
244
  };
245
+ /** Child path using the archive's spelling of one anatomy name. */
246
+ const namedChild = (tree, directory, expected) => {
247
+ const name = anatomyChild(tree.children.get(directory), expected);
248
+ return name === null ? null : joinPath(directory, name);
249
+ };
199
250
  const infoPlistPath = (bundle, layout, tree) => {
200
251
  const directories = contentDirectories(bundle, layout, tree);
201
252
  // With several real versions, Versions/Current (a symlink outside the
202
253
  // inventory) decides which plist applies, so the plist stays unknown.
203
254
  if (directories.length !== 1)
204
255
  return null;
205
- const candidates = directories
206
- .map((directory) => joinPath(directory, layout === "versioned-framework"
207
- ? "Resources/Info.plist"
208
- : "Info.plist"))
209
- .filter((path) => tree.files.has(path));
210
- return candidates.length === 1 ? (candidates[0] ?? null) : null;
256
+ const directory = directories[0];
257
+ if (directory === undefined)
258
+ return null;
259
+ const parent = layout === "versioned-framework"
260
+ ? namedChild(tree, directory, "Resources")
261
+ : directory;
262
+ if (parent === null)
263
+ return null;
264
+ const info = namedChild(tree, parent, "Info.plist");
265
+ return info !== null && tree.files.has(info) ? info : null;
211
266
  };
212
267
  const executableCandidates = (bundle, layout, tree) => contentDirectories(bundle, layout, tree)
213
- .flatMap((directory) => directFiles(layout === "macos-deep" ? joinPath(directory, "MacOS") : directory, tree))
268
+ .flatMap((directory) => {
269
+ const executableDirectory = layout === "macos-deep"
270
+ ? namedChild(tree, directory, "MacOS")
271
+ : directory;
272
+ return executableDirectory === null
273
+ ? []
274
+ : directFiles(executableDirectory, tree);
275
+ })
214
276
  .filter((path) => MACH_O_FORMATS.includes(tree.files.get(path)?.format ?? ""));
215
277
  const signingPaths = (bundle, layout, tree) => contentDirectories(bundle, layout, tree)
216
- .flatMap((directory) => [
217
- joinPath(directory, "_CodeSignature/CodeResources"),
218
- joinPath(directory, "embedded.provisionprofile"),
219
- joinPath(directory, "embedded.mobileprovision"),
220
- ])
221
- .filter((path) => tree.files.has(path))
278
+ .flatMap((directory) => {
279
+ const signature = namedChild(tree, directory, "_CodeSignature");
280
+ return [
281
+ signature === null
282
+ ? null
283
+ : namedChild(tree, signature, "CodeResources"),
284
+ namedChild(tree, directory, "embedded.provisionprofile"),
285
+ namedChild(tree, directory, "embedded.mobileprovision"),
286
+ ];
287
+ })
288
+ .filter((path) => path !== null && tree.files.has(path))
222
289
  .sort(compare);
223
290
  /** Platforms of application roots whose layout was observed, not assumed. */
224
291
  export const platformsOf = (bundles) => [
@@ -11,6 +11,8 @@ export const resolveTreePath = async (view, input) => {
11
11
  let hops = 0;
12
12
  while (pending.length > 0) {
13
13
  const segment = pending.shift() ?? "";
14
+ if (segment === ".")
15
+ continue;
14
16
  if (segment === "..") {
15
17
  if (resolved.length === 0)
16
18
  return { kind: "escapes" };
@@ -40,7 +42,13 @@ export const resolveTreePath = async (view, input) => {
40
42
  ? { kind: "file", path: resolved.join("/") }
41
43
  : { kind: "not-file" };
42
44
  };
43
- const segmentsOf = (path) => path.split("/").filter((segment) => segment !== "" && segment !== ".");
45
+ const segmentsOf = (path) => {
46
+ const segments = path.split("/").filter((segment) => segment !== "");
47
+ // a trailing slash requires a directory, just like a final dot component.
48
+ if (path.endsWith("/"))
49
+ segments.push(".");
50
+ return segments;
51
+ };
44
52
  export const directoryOf = (path) => {
45
53
  const index = path.lastIndexOf("/");
46
54
  return index < 0 ? "" : path.slice(0, index);
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { compatibleSlice, directoryOf, expandPrefix, joinPath, resolveTreePath, } from "./dyldPaths.js";
2
+ import { compatibleSlice, directoryOf, expandPrefix, resolveTreePath, } from "./dyldPaths.js";
3
3
  import { digestSchema } from "../digests.js";
4
4
  import { hasApplicableDyldOverrides, embeddedDyldOverrides, } from "./dyldEnvironment.js";
5
5
  import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, } from "./dylibResolutionFindings.js";
@@ -8,7 +8,7 @@ import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, } from "./dylibResolution
8
8
  * `/`, none of them `.` or `..`, without backslash or NUL. Advertised schema
9
9
  * patterns avoid look-around, which RE2 and Rust validators reject.
10
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;
11
+ const ROOT_RELATIVE_PATH = /^(?:[^\x2f\\\x00.][^\x2f\\\x00]*|\.[^\x2f\\\x00.][^\x2f\\\x00]*|\.\.[^\x2f\\\x00]+)(?:\x2f(?:[^\x2f\\\x00.][^\x2f\\\x00]*|\.[^\x2f\\\x00.][^\x2f\\\x00]*|\.\.[^\x2f\\\x00]+))*$/u;
12
12
  const rootRelativePathSchema = z
13
13
  .string()
14
14
  .min(1)
@@ -169,7 +169,7 @@ const candidateTemplates = (dependency, loader, context) => {
169
169
  scope: base.scope,
170
170
  path: base.scope === "outside"
171
171
  ? `${base.path.replace(/\/+$/u, "")}/${rest}`
172
- : joinPath(base.path, rest),
172
+ : `${base.path}${base.path === "" ? "" : "/"}${rest}`,
173
173
  };
174
174
  return { expansion, source: "rpath", rpath, rpathOwner: owner };
175
175
  }));
@@ -30,13 +30,16 @@ export const buildInterfaceBuilderAnalysis = (input) => {
30
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
- const prefix = `ib:${document.relativePath}:`;
33
+ const prefix = `ib:${JSON.stringify(document.relativePath)}:`;
34
+ const graphId = (kind, parts = []) => `${prefix}${kind}:${JSON.stringify(parts)}`;
34
35
  const rootId = `${prefix}root`;
35
36
  const objectIds = new Set(parsed.objects.map(({ id }) => id));
36
37
  const evidenceFor = (description) => [
37
38
  {
38
39
  kind: "interface_builder_resource",
39
- description: `${document.relativePath}: ${description}`,
40
+ // artifact_path names the archive; repeating it here cost a path per
41
+ // node and edge.
42
+ description,
40
43
  location: { address: null, file_offset: null },
41
44
  artifact_path: document.relativePath,
42
45
  artifact_sha256: document.archiveSha256,
@@ -66,7 +69,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
66
69
  addNode(rootNode);
67
70
  let documentObjectCount = 0;
68
71
  for (const object of parsed.objects.slice(0, input.limits.max_objects)) {
69
- const id = `${prefix}object:${object.id}`;
72
+ const id = graphId("object", [object.id]);
70
73
  const kind = object.kind === "other" ? "unknown" : object.kind;
71
74
  if (!addNode({
72
75
  id,
@@ -88,7 +91,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
88
91
  let hierarchyEdgeCount = 0;
89
92
  let documentOmittedConnections = 0;
90
93
  let documentOmittedHierarchyEdges = 0;
91
- const objectNodeId = (objectId) => `${prefix}object:${objectId}`;
94
+ const objectNodeId = (objectId) => graphId("object", [objectId]);
92
95
  const addEdge = (edge, isHierarchy) => {
93
96
  if (isHierarchy
94
97
  ? hierarchyEdgeCount >= input.limits.max_objects
@@ -181,7 +184,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
181
184
  const known = objectIds.has(objectId);
182
185
  const childId = known
183
186
  ? objectNodeId(objectId)
184
- : `${prefix}unknown:${objectId}`;
187
+ : graphId("unknown", [objectId]);
185
188
  if (!known &&
186
189
  !addNode({
187
190
  id: childId,
@@ -192,7 +195,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
192
195
  evidence: evidenceFor(`hierarchy item ${objectId}`),
193
196
  }))
194
197
  hierarchyTruncated = true;
195
- connect(`${prefix}hierarchy:${parentId}:${childId}`, parentId, childId, "contains", `hierarchy ${objectId}`);
198
+ connect(graphId("hierarchy", [parentId, childId]), parentId, childId, "contains", `hierarchy ${objectId}`);
196
199
  nextParent = childId;
197
200
  hierarchyCount += 1;
198
201
  }
@@ -216,10 +219,10 @@ export const buildInterfaceBuilderAnalysis = (input) => {
216
219
  });
217
220
  const destinationId = item.destination_id === null ? null : objectNodeId(item.destination_id);
218
221
  if (item.kind === "action") {
219
- const actionId = `${prefix}action:${item.id}`;
222
+ const actionId = graphId("action", [item.id]);
220
223
  const selectorId = item.label === null
221
224
  ? null
222
- : `${prefix}selector:${item.destination_id ?? "unknown"}:${item.label}`;
225
+ : graphId("selector", [item.destination_id, item.label]);
223
226
  addNode({
224
227
  id: actionId,
225
228
  kind: "action",
@@ -232,7 +235,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
232
235
  },
233
236
  evidence: evidenceFor(`action ${item.id}`),
234
237
  });
235
- connect(`${actionId}:source`, sourceId, actionId, "target_action", `action source ${item.source_id}`);
238
+ connect(graphId("action-edge", [item.id, "source"]), sourceId, actionId, "target_action", `action source ${item.source_id}`);
236
239
  if (selectorId !== null) {
237
240
  addNode({
238
241
  id: selectorId,
@@ -242,15 +245,15 @@ export const buildInterfaceBuilderAnalysis = (input) => {
242
245
  attributes: { destination_id: item.destination_id },
243
246
  evidence: evidenceFor(`selector ${item.label}`),
244
247
  });
245
- connect(`${actionId}:selector`, actionId, selectorId, "target_action", `selector ${item.label}`);
248
+ connect(graphId("action-edge", [item.id, "selector"]), actionId, selectorId, "target_action", `selector ${item.label}`);
246
249
  }
247
250
  if (destinationId === null || !nodes.has(destinationId))
248
- connect(`${actionId}:destination`, actionId, null, "target_action", `action destination ${item.destination_id ?? "missing"}`, "destination_object_missing_or_external");
251
+ connect(graphId("action-edge", [item.id, "destination"]), actionId, null, "target_action", `action destination ${item.destination_id ?? "missing"}`, "destination_object_missing_or_external");
249
252
  else
250
- connect(`${actionId}:destination`, actionId, destinationId, "target_action", `action destination ${item.destination_id}`);
253
+ connect(graphId("action-edge", [item.id, "destination"]), actionId, destinationId, "target_action", `action destination ${item.destination_id}`);
251
254
  }
252
255
  else if (item.kind === "outlet") {
253
- const outletId = `${prefix}outlet:${item.id}`;
256
+ const outletId = graphId("outlet", [item.id]);
254
257
  addNode({
255
258
  id: outletId,
256
259
  kind: "outlet",
@@ -259,20 +262,20 @@ export const buildInterfaceBuilderAnalysis = (input) => {
259
262
  attributes: item.attributes,
260
263
  evidence: evidenceFor(`outlet ${item.id}`),
261
264
  });
262
- connect(`${outletId}:source`, sourceId, outletId, "contains", `outlet source ${item.source_id}`);
265
+ connect(graphId("outlet-edge", [item.id, "source"]), sourceId, outletId, "contains", `outlet source ${item.source_id}`);
263
266
  if (destinationId === null || !nodes.has(destinationId))
264
- connect(`${outletId}:destination`, outletId, null, "outlet_to", `outlet ${item.label ?? item.id}`, "destination_object_missing_or_external");
267
+ connect(graphId("outlet-edge", [item.id, "destination"]), outletId, null, "outlet_to", `outlet ${item.label ?? item.id}`, "destination_object_missing_or_external");
265
268
  else
266
- connect(`${outletId}:destination`, outletId, destinationId, "outlet_to", `outlet ${item.label ?? item.id}`);
269
+ connect(graphId("outlet-edge", [item.id, "destination"]), outletId, destinationId, "outlet_to", `outlet ${item.label ?? item.id}`);
267
270
  }
268
271
  else if (item.kind === "segue") {
269
272
  if (destinationId === null || !nodes.has(destinationId))
270
- connect(`${prefix}segue:${index}`, sourceId, null, "segue_to", `segue ${item.label ?? item.id}`, "destination_scene_missing");
273
+ connect(graphId("segue", [index]), sourceId, null, "segue_to", `segue ${item.label ?? item.id}`, "destination_scene_missing");
271
274
  else
272
- connect(`${prefix}segue:${index}`, sourceId, destinationId, "segue_to", `segue ${item.label ?? item.id}`);
275
+ connect(graphId("segue", [index]), sourceId, destinationId, "segue_to", `segue ${item.label ?? item.id}`);
273
276
  }
274
277
  else {
275
- connect(`${prefix}unknown-connection:${index}`, sourceId, null, "contains", `connection type ${item.kind}`, "unsupported_connection_type");
278
+ connect(graphId("unknown-connection", [index]), sourceId, null, "contains", `connection type ${item.kind}`, "unsupported_connection_type");
276
279
  }
277
280
  }
278
281
  const objectsTruncated = parsed.omittedObjects > 0 || parsed.objects.length > documentObjectCount;
@@ -44,12 +44,21 @@ export const parseInterfaceBuilderRecords = (value) => {
44
44
  const attributes = record(raw);
45
45
  const className = firstString(attributes["customClass"], attributes["class"], attributes["isa"]);
46
46
  const label = firstString(attributes["label"], attributes["title"], attributes["name"], className);
47
+ // class_name, name, and id already carry these values; repeating them in
48
+ // attributes doubled them on every graph node.
49
+ const carried = new Set();
50
+ if (attributes["customClass"] === className)
51
+ carried.add("customClass");
52
+ if (attributes["label"] === label)
53
+ carried.add("label");
54
+ if (attributes["objectID"] === id)
55
+ carried.add("objectID");
47
56
  objects.push(objectNode.parse({
48
57
  id,
49
58
  kind: classifyObject(className),
50
59
  class_name: className,
51
60
  name: label ?? id,
52
- attributes: jsonSafeRecord(attributes),
61
+ attributes: jsonSafeRecord(Object.fromEntries(Object.entries(attributes).filter(([key]) => !carried.has(key)))),
53
62
  }));
54
63
  }
55
64
  for (const [sourceId, rawConnections] of Object.entries(connectionsRaw)) {
@@ -1,10 +1,11 @@
1
- import { compareCodePoints } from "./canonicalOrdering.js";
1
+ import { compareUnicodeCodePoints } from "./unicodeCodePointOrder.js";
2
2
  import { z } from "zod";
3
3
  import {} from "./artifactGraph.js";
4
4
  import { evidenceSchema } from "./evidence.js";
5
5
  import { parseArtifactInventoryEvidence, } from "./artifactInventoryEvidence.js";
6
6
  import { prefixedDigestSchema } from "./../domain/digests.js";
7
7
  import { canonicalJson } from "./comparisonSemantics.js";
8
+ import { ZIP_NON_ENTRY_TAIL_LIMITATION } from "./zipPackageFormat.js";
8
9
  const evidenceIdSchema = prefixedDigestSchema("ev");
9
10
  const comparisonStatusSchema = z.enum([
10
11
  "unchanged",
@@ -95,6 +96,12 @@ export const compareArtifacts = (leftEvidence, rightEvidence) => {
95
96
  ...left.evidence.map(({ evidence_id: id }) => id),
96
97
  ...right.evidence.map(({ evidence_id: id }) => id),
97
98
  ], leftCovered && rightCovered);
99
+ const rootChange = rootHashChange(left.inventory, right.inventory, changes, [
100
+ ...left.evidence.map(({ evidence_id: id }) => id),
101
+ ...right.evidence.map(({ evidence_id: id }) => id),
102
+ ]);
103
+ if (rootChange !== null)
104
+ changes.push(rootChange);
98
105
  const summary = summarize(left.inventory, right.inventory, changes, leftCovered && rightCovered);
99
106
  return artifactComparisonResultSchema.parse({
100
107
  status: !leftComplete || !rightComplete
@@ -112,7 +119,7 @@ export const compareArtifacts = (leftEvidence, rightEvidence) => {
112
119
  right_manifest_id: right.inventory.manifest.manifest_id,
113
120
  summary,
114
121
  changes,
115
- limitations: [...new Set(limitations)].sort(compareCodePoints),
122
+ limitations: [...new Set(limitations)].sort(compareUnicodeCodePoints),
116
123
  });
117
124
  };
118
125
  const compareOccurrences = (left, right, evidenceLinks, complete) => {
@@ -124,7 +131,7 @@ const compareOccurrences = (left, right, evidenceLinks, complete) => {
124
131
  const rightRelations = relationsByPath(right);
125
132
  const paths = [
126
133
  ...new Set([...leftByPath.keys(), ...rightByPath.keys()]),
127
- ].sort(compareCodePoints);
134
+ ].sort(compareUnicodeCodePoints);
128
135
  const output = [];
129
136
  for (const path of paths) {
130
137
  const leftOccurrence = leftByPath.get(path);
@@ -251,18 +258,20 @@ const relationsByPath = (inventory) => {
251
258
  const output = new Map();
252
259
  const occurrences = new Map(inventory.occurrences.map((item) => [item.occurrence_id, item]));
253
260
  for (const edge of inventory.edges) {
254
- const path = edge.logical_path ?? ".";
255
- const values = output.get(path);
256
261
  const occurrence = occurrences.get(edge.occurrence_id);
262
+ // An incomplete inventory can omit the occurrence that names the child.
263
+ if (occurrence?.artifact_id === null || occurrence === undefined)
264
+ continue;
265
+ const path = occurrence.logical_path;
266
+ const values = output.get(path);
257
267
  const projection = {
258
- parent_logical_path: occurrence?.parent_occurrence_id === null ||
259
- occurrence?.parent_occurrence_id === undefined
268
+ parent_logical_path: occurrence.parent_occurrence_id === null
260
269
  ? null
261
270
  : (occurrences.get(occurrence.parent_occurrence_id)?.logical_path ??
262
271
  null),
263
- child_artifact_id: edge.child_artifact_id,
272
+ child_artifact_id: occurrence.artifact_id,
264
273
  relation: edge.relation,
265
- logical_path: edge.logical_path,
274
+ logical_path: occurrence.logical_path,
266
275
  producer: edge.producer,
267
276
  };
268
277
  if (values === undefined)
@@ -271,7 +280,7 @@ const relationsByPath = (inventory) => {
271
280
  values.push(projection);
272
281
  }
273
282
  for (const values of output.values())
274
- values.sort((left, right) => compareCodePoints(canonicalJson(left), canonicalJson(right)));
283
+ values.sort((left, right) => compareUnicodeCodePoints(canonicalJson(left), canonicalJson(right)));
275
284
  return output;
276
285
  };
277
286
  const summarize = (left, right, changes, covered) => {
@@ -302,4 +311,23 @@ const summarize = (left, right, changes, covered) => {
302
311
  counts.contradiction),
303
312
  };
304
313
  };
305
- const hasCoverageLimitation = (limitations) => limitations.some((limitation) => !/integrity contradiction\(s\) were recorded/u.test(limitation));
314
+ const hasCoverageLimitation = (limitations) => limitations.some((limitation) => limitation !== ZIP_NON_ENTRY_TAIL_LIMITATION &&
315
+ !/integrity contradiction\(s\) were recorded/u.test(limitation));
316
+ const rootHashChange = (left, right, changes, evidenceLinks) => {
317
+ if (left.manifest.root_sha256 === right.manifest.root_sha256)
318
+ return null;
319
+ if (changes.some((change) => change.logical_path === "." && change.dimensions.includes("content")))
320
+ return null;
321
+ const leftRoot = left.occurrences.find((occurrence) => occurrence.logical_path === ".");
322
+ const rightRoot = right.occurrences.find((occurrence) => occurrence.logical_path === ".");
323
+ return {
324
+ classification: "changed",
325
+ logical_path: ".",
326
+ dimensions: ["content"],
327
+ left_occurrence_id: leftRoot?.occurrence_id ?? null,
328
+ right_occurrence_id: rightRoot?.occurrence_id ?? null,
329
+ left_artifact_id: leftRoot?.artifact_id ?? null,
330
+ right_artifact_id: rightRoot?.artifact_id ?? null,
331
+ evidence_links: [...evidenceLinks],
332
+ };
333
+ };
@@ -121,7 +121,7 @@ const artifactOccurrenceSchema = z.object({
121
121
  limitations: z.array(z.string()),
122
122
  });
123
123
  /** Observed bytes that contradict a container's declared integrity identity. */
124
- const integrityContradictionSchema = z.object({
124
+ export const integrityContradictionSchema = z.object({
125
125
  contradiction_id: contradictionIdSchema,
126
126
  occurrence_id: occurrenceIdSchema,
127
127
  parent_artifact_id: artifactIdSchema,
@@ -134,12 +134,14 @@ const integrityContradictionSchema = z.object({
134
134
  provenance: z.literal("container-integrity-metadata-versus-observed-bytes"),
135
135
  limitations: z.array(z.string()).min(1),
136
136
  });
137
- /** Parent-child derivation relation between two content-addressed artifacts. */
137
+ /**
138
+ * Parent-child derivation relation between two content-addressed artifacts.
139
+ * The child artifact and its logical path are those of the edge's occurrence.
140
+ */
138
141
  const artifactEdgeSchema = z.object({
139
142
  edge_id: edgeIdSchema,
140
143
  ordinal: z.number().int().min(0),
141
144
  parent_artifact_id: artifactIdSchema,
142
- child_artifact_id: artifactIdSchema,
143
145
  relation: z.enum([
144
146
  "contains",
145
147
  "extracts",
@@ -150,7 +152,6 @@ const artifactEdgeSchema = z.object({
150
152
  "derived-from",
151
153
  ]),
152
154
  occurrence_id: occurrenceIdSchema,
153
- logical_path: boundedRelativePathSchema.nullable(),
154
155
  producer: artifactCommandSchema.nullable(),
155
156
  });
156
157
  /** Stable cryptographic commitment and counts for a complete artifact graph. */
@@ -203,5 +204,6 @@ export const artifactExtractionResultSchema = z.object({
203
204
  residual_paths: z.array(boundedRelativePathSchema),
204
205
  }),
205
206
  provenance: z.array(artifactCommandSchema),
207
+ integrity_contradictions: z.array(integrityContradictionSchema),
206
208
  limitations: z.array(z.string()),
207
209
  });