@oneuptime/common 13.0.4 → 13.0.6

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 (1589) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +81 -1
  2. package/Models/AnalyticsModels/SecurityEvent.ts +4 -4
  3. package/Models/DatabaseModels/Alert.ts +62 -0
  4. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  5. package/Models/DatabaseModels/Incident.ts +66 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +74 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +74 -0
  8. package/Models/DatabaseModels/Index.ts +10 -4
  9. package/Models/DatabaseModels/NetworkDevice.ts +67 -0
  10. package/Models/DatabaseModels/NetworkDeviceDiagnostic.ts +746 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +151 -0
  12. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +1 -1
  13. package/Models/DatabaseModels/Project.ts +41 -0
  14. package/Models/DatabaseModels/RumApplication.ts +1 -1
  15. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +74 -0
  16. package/Models/DatabaseModels/{GoogleSecOpsConnection.ts → SecurityEventConnection.ts} +61 -51
  17. package/Models/DatabaseModels/{GoogleSecOpsConnectionRun.ts → SecurityEventConnectionRun.ts} +24 -24
  18. package/Models/DatabaseModels/ServiceLevelObjective.ts +185 -8
  19. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +746 -43
  20. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +575 -0
  21. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +582 -0
  22. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +16 -0
  23. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +16 -0
  24. package/Models/DatabaseModels/StatusPageAnnouncement.ts +75 -0
  25. package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
  26. package/Models/DatabaseModels/ThreatIntelFeed.ts +1 -1
  27. package/Server/API/AIInvestigationAPI.ts +484 -24
  28. package/Server/API/BaseAPI.ts +17 -0
  29. package/Server/API/BillingInvoiceAPI.ts +343 -30
  30. package/Server/API/BillingPaymentMethodAPI.ts +126 -5
  31. package/Server/API/DashboardAPI.ts +96 -2
  32. package/Server/API/SecurityEventConnectionAPI.ts +380 -0
  33. package/Server/API/StatusPageAPI.ts +308 -199
  34. package/Server/API/TelemetryAPI.ts +402 -265
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.ts +83 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.ts +36 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.ts +29 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.ts +516 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.ts +98 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.ts +27 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.ts +97 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
  44. package/Server/Middleware/TelemetryIngest.ts +101 -6
  45. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +138 -67
  46. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +213 -84
  47. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +112 -35
  48. package/Server/Services/AlertLabelRuleEngineService.ts +299 -217
  49. package/Server/Services/AlertOwnerRuleEngineService.ts +572 -396
  50. package/Server/Services/AlertPrivacyRuleEngineService.ts +116 -40
  51. package/Server/Services/AlertService.ts +111 -4
  52. package/Server/Services/AuditLogService.ts +612 -59
  53. package/Server/Services/BillingInvoiceService.ts +112 -102
  54. package/Server/Services/BillingService.ts +539 -11
  55. package/Server/Services/CephClusterLabelRuleEngineService.ts +170 -109
  56. package/Server/Services/CephClusterOwnerRuleEngineService.ts +233 -115
  57. package/Server/Services/CloudResourceLabelRuleEngineService.ts +163 -100
  58. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +236 -115
  59. package/Server/Services/DashboardLabelRuleEngineService.ts +145 -84
  60. package/Server/Services/DashboardOwnerRuleEngineService.ts +213 -95
  61. package/Server/Services/DatabaseService.ts +171 -21
  62. package/Server/Services/DockerHostLabelRuleEngineService.ts +171 -110
  63. package/Server/Services/DockerHostOwnerRuleEngineService.ts +233 -115
  64. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +181 -112
  65. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +243 -118
  66. package/Server/Services/ExceptionAggregationService.ts +7 -16
  67. package/Server/Services/HostLabelRuleEngineService.ts +167 -106
  68. package/Server/Services/HostOwnerRuleEngineService.ts +229 -111
  69. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +141 -67
  70. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +272 -72
  71. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +112 -35
  72. package/Server/Services/IncidentEpisodePublicNoteService.ts +24 -0
  73. package/Server/Services/IncidentLabelRuleEngineService.ts +279 -204
  74. package/Server/Services/IncidentOwnerRuleEngineService.ts +595 -425
  75. package/Server/Services/IncidentPrivacyRuleEngineService.ts +117 -44
  76. package/Server/Services/IncidentPublicNoteService.ts +24 -0
  77. package/Server/Services/IncidentService.ts +114 -3
  78. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +147 -83
  79. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +221 -100
  80. package/Server/Services/Index.ts +10 -4
  81. package/Server/Services/InventoryItemService.ts +28 -0
  82. package/Server/Services/IoTFleetLabelRuleEngineService.ts +145 -84
  83. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +213 -95
  84. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +181 -112
  85. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +243 -118
  86. package/Server/Services/LabelService.ts +23 -28
  87. package/Server/Services/LogAggregationService.ts +17 -23
  88. package/Server/Services/MetricAggregationService.ts +4 -14
  89. package/Server/Services/MonitorLabelRuleEngineService.ts +152 -92
  90. package/Server/Services/MonitorOwnerRuleEngineService.ts +220 -104
  91. package/Server/Services/MonitorProbeService.ts +20 -2
  92. package/Server/Services/MonitorService.ts +11 -9
  93. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +376 -5
  94. package/Server/Services/NetworkDeviceDiagnosticService.ts +417 -0
  95. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +147 -83
  96. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +218 -97
  97. package/Server/Services/NetworkDeviceService.ts +39 -2
  98. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +151 -80
  99. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +222 -97
  100. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +154 -83
  101. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +225 -100
  102. package/Server/Services/PodmanHostLabelRuleEngineService.ts +171 -110
  103. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +235 -115
  104. package/Server/Services/ProjectService.ts +111 -10
  105. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +174 -110
  106. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +239 -116
  107. package/Server/Services/RumApplicationLabelRuleEngineService.ts +137 -73
  108. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +200 -83
  109. package/Server/Services/RunbookLabelRuleEngineService.ts +146 -84
  110. package/Server/Services/RunbookOwnerRuleEngineService.ts +216 -95
  111. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +324 -230
  112. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +613 -428
  113. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +24 -0
  114. package/Server/Services/ScheduledMaintenanceService.ts +43 -14
  115. package/Server/Services/{GoogleSecOpsConnectionRunService.ts → SecurityEventConnectionRunService.ts} +1 -1
  116. package/Server/Services/SecurityEventConnectionService.ts +590 -0
  117. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +143 -74
  118. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +206 -85
  119. package/Server/Services/ServiceLabelRuleEngineService.ts +172 -110
  120. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +1057 -18
  121. package/Server/Services/ServiceLevelObjectiveFeedService.ts +108 -0
  122. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +793 -97
  123. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +1069 -0
  124. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +240 -1
  125. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +257 -1
  126. package/Server/Services/ServiceLevelObjectiveService.ts +1356 -56
  127. package/Server/Services/ServiceOwnerRuleEngineService.ts +238 -116
  128. package/Server/Services/StatusPageAnnouncementService.ts +13 -0
  129. package/Server/Services/StatusPageLabelRuleEngineService.ts +146 -85
  130. package/Server/Services/StatusPageOwnerRuleEngineService.ts +210 -99
  131. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +28 -232
  132. package/Server/Services/StatusPageSubscriberService.ts +6 -0
  133. package/Server/Services/TelemetryUsageBillingService.ts +38 -7
  134. package/Server/Services/ThreatIntelFeedService.ts +1 -1
  135. package/Server/Services/TraceAggregationService.ts +77 -28
  136. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +173 -110
  137. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +238 -116
  138. package/Server/Services/WorkflowLabelRuleEngineService.ts +145 -84
  139. package/Server/Services/WorkflowOwnerRuleEngineService.ts +215 -95
  140. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
  141. package/Server/Types/Database/UpdateByID.ts +3 -0
  142. package/Server/Types/Database/UpdateOneBy.ts +7 -0
  143. package/Server/Utils/AI/AlertAIContextBuilder.ts +19 -0
  144. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
  145. package/Server/Utils/AI/IncidentAIContextBuilder.ts +39 -0
  146. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
  147. package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
  148. package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
  149. package/Server/Utils/AI/Toolbox/AlertTools.ts +37 -1
  150. package/Server/Utils/AI/Toolbox/IncidentTools.ts +22 -1
  151. package/Server/Utils/AI/Toolbox/Index.ts +38 -0
  152. package/Server/Utils/AI/Toolbox/SloTools.ts +416 -51
  153. package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
  154. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
  155. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +151 -13
  156. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +17 -4
  157. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +155 -8
  158. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +16 -0
  159. package/Server/Utils/Database/RelationValueUtil.ts +106 -0
  160. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +6 -1
  161. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +22 -27
  162. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
  163. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +3 -1
  164. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +50 -20
  165. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +13 -1
  166. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +6 -11
  167. package/Server/Utils/Rules/MonitorRulePatternValidator.ts +51 -0
  168. package/Server/Utils/Rules/OwnerRuleAssignment.ts +110 -0
  169. package/Server/Utils/Rules/RuleRun/RuleApplication.ts +81 -0
  170. package/Server/Utils/Rules/RuleRun/RuleRunPermission.ts +188 -0
  171. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +803 -0
  172. package/Server/Utils/Rules/RuleRun/RuleRunner.ts +341 -0
  173. package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +3 -2
  174. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
  175. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
  176. package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +497 -0
  177. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
  178. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
  179. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
  180. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
  181. package/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.ts +609 -74
  182. package/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.ts +2101 -0
  183. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
  184. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
  185. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
  186. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
  187. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
  188. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
  189. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1182 -0
  190. package/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.ts → Connectors/SecurityEventConnectionRunExecutor.ts} +165 -76
  191. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +306 -0
  192. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +55 -0
  193. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
  194. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
  195. package/Server/Utils/SecurityEvent/Connectors/Types.ts +431 -0
  196. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +1 -1
  197. package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
  198. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +2 -2
  199. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +902 -40
  200. package/Server/Utils/Slo/SloFeedUtil.ts +200 -0
  201. package/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.ts +173 -0
  202. package/Server/Utils/Slo/SloMetricUtil.ts +327 -0
  203. package/Server/Utils/Slo/SloOwnerReferenceValidator.ts +208 -0
  204. package/Server/Utils/Slo/SloRecordReferenceValidator.ts +169 -0
  205. package/Server/Utils/StartServer.ts +10 -0
  206. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +6 -43
  207. package/Server/Utils/StatusPageResource.ts +50 -5
  208. package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
  209. package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
  210. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
  211. package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
  212. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
  213. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
  214. package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
  215. package/Server/Utils/Telemetry.ts +18 -0
  216. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +1063 -1
  217. package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
  218. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +4 -1
  219. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
  220. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +307 -0
  221. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
  222. package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +289 -0
  223. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +598 -0
  224. package/Tests/App/Dashboard/BillingDefaultPaymentMethod.test.tsx +1046 -0
  225. package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +3 -0
  226. package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +201 -7
  227. package/Tests/App/Dashboard/BooleanSeriesCriteriaFilterText.test.ts +82 -0
  228. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +16 -1
  229. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +943 -0
  230. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +168 -1
  231. package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
  232. package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
  233. package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +755 -0
  234. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +1095 -1
  235. package/Tests/App/Dashboard/CorrelateFilterChips.test.tsx +910 -0
  236. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +3747 -25
  237. package/Tests/App/Dashboard/CorrelateGraphHelpers.test.ts +1085 -0
  238. package/Tests/App/Dashboard/CorrelateInspector.test.tsx +1534 -0
  239. package/Tests/App/Dashboard/CorrelateNodeCard.test.tsx +965 -0
  240. package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +1525 -0
  241. package/Tests/App/Dashboard/CorrelationGraph.test.ts +1030 -0
  242. package/Tests/App/Dashboard/CorrelationGraphLayout.test.ts +526 -0
  243. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
  244. package/Tests/App/Dashboard/DeviceDiagnostics.test.tsx +787 -0
  245. package/Tests/App/Dashboard/DeviceLatencyTrend.test.tsx +278 -0
  246. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +279 -0
  247. package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +87 -0
  248. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +443 -8
  249. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
  250. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +340 -0
  251. package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
  252. package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
  253. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2450 -0
  254. package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
  255. package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
  256. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
  257. package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
  258. package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
  259. package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
  260. package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
  261. package/Tests/App/Dashboard/ExceptionSegmentedControl.test.tsx +1020 -0
  262. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
  263. package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
  264. package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
  265. package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
  266. package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
  267. package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
  268. package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
  269. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
  270. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
  271. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
  272. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1472 -0
  273. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
  274. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1931 -25
  275. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +159 -2
  276. package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
  277. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1398 -0
  278. package/Tests/App/Dashboard/InvestigationRunDetails.test.tsx +1166 -0
  279. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +437 -0
  280. package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
  281. package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
  282. package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
  283. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
  284. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +65 -0
  285. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +5 -0
  286. package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
  287. package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
  288. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
  289. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +74 -0
  290. package/Tests/App/Dashboard/ResourceFeed.test.tsx +125 -5
  291. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  292. package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
  293. package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
  294. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
  295. package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
  296. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
  297. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
  298. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +1764 -0
  299. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1958 -0
  300. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +448 -0
  301. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +1455 -0
  302. package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +233 -0
  303. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +282 -0
  304. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
  305. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
  306. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
  307. package/Tests/App/Dashboard/SloActiveBurnEventsCard.test.tsx +538 -0
  308. package/Tests/App/Dashboard/SloBulkActionsArchive.test.tsx +252 -0
  309. package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +322 -518
  310. package/Tests/App/Dashboard/SloElement.test.tsx +194 -0
  311. package/Tests/App/Dashboard/SloFeed.test.tsx +289 -0
  312. package/Tests/App/Dashboard/SloHistoryCharts.test.tsx +471 -0
  313. package/Tests/App/Dashboard/SloHistorySeries.test.tsx +607 -0
  314. package/Tests/App/Dashboard/SloListWidget.test.tsx +783 -0
  315. package/Tests/App/Dashboard/SloMetricsPage.test.tsx +346 -0
  316. package/Tests/App/Dashboard/SloMonitorsPage.test.tsx +661 -0
  317. package/Tests/App/Dashboard/SloMonitorsSummaryCard.test.tsx +489 -0
  318. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +437 -0
  319. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +305 -0
  320. package/Tests/App/Dashboard/SloOverviewData.test.tsx +563 -0
  321. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +311 -0
  322. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +426 -0
  323. package/Tests/App/Dashboard/SloOverviewSidebarCards.test.tsx +493 -0
  324. package/Tests/App/Dashboard/SloSettings.test.tsx +633 -0
  325. package/Tests/App/Dashboard/SloStatusSummaryCards.test.tsx +403 -0
  326. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +373 -0
  327. package/Tests/App/Dashboard/SloWidgetVariableBinding.test.tsx +689 -0
  328. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
  329. package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
  330. package/Tests/App/Dashboard/TopologyConnectivitySection.test.tsx +206 -0
  331. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
  332. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
  333. package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
  334. package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
  335. package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
  336. package/Tests/App/Dashboard/TracesEntityNames.test.tsx +617 -0
  337. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
  338. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +1312 -0
  339. package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
  340. package/Tests/App/Dashboard/WidgetCatalog.test.ts +9 -1
  341. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +14 -16
  342. package/Tests/Models/DatabaseModels/AuditLogModelConfiguration.test.ts +442 -0
  343. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +13 -7
  344. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +48 -1
  345. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +835 -0
  346. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +3 -2
  347. package/Tests/Models/DiscoveryScanNetbiosLookupColumn.test.ts +328 -0
  348. package/Tests/Models/DiscoveryScanShortDeviceNamesColumn.test.ts +335 -0
  349. package/Tests/Models/InventoryItemNaming.test.ts +132 -16
  350. package/Tests/Models/NetworkDeviceDiagnosticContract.test.ts +194 -0
  351. package/Tests/Models/NetworkDeviceDnsNameColumn.test.ts +321 -0
  352. package/Tests/Models/ProjectDataResidencyColumn.test.ts +154 -0
  353. package/Tests/Models/SecurityDomainAccessControl.test.ts +197 -22
  354. package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
  355. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
  356. package/Tests/Server/API/BaseAPI.test.ts +6 -0
  357. package/Tests/Server/API/BaseAPIUpdateMiscDataProps.test.ts +217 -0
  358. package/Tests/Server/API/BillingInvoiceAPI.test.ts +7 -0
  359. package/Tests/Server/API/BillingInvoiceAPIPaymentStates.test.ts +990 -0
  360. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +498 -0
  361. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +405 -0
  362. package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +1750 -0
  363. package/Tests/Server/API/SessionReplayAPI.test.ts +644 -1
  364. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +857 -0
  365. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +1084 -0
  366. package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
  367. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
  368. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +33 -3
  369. package/Tests/Server/Infrastructure/Postgres/AddDataResidencyToProjectMigration.test.ts +202 -0
  370. package/Tests/Server/Infrastructure/Postgres/AddNetbiosLookupToNetworkDeviceDiscoveryScanMigration.test.ts +330 -0
  371. package/Tests/Server/Infrastructure/Postgres/AddNetworkDeviceDnsNameAndShortDeviceNamesMigration.test.ts +340 -0
  372. package/Tests/Server/Infrastructure/Postgres/BackfillSloMonitorRulesAndAffectedResourcesMigration.test.ts +343 -0
  373. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +801 -0
  374. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
  375. package/Tests/Server/Services/AddSubscriberUpdateNotificationStatusMigration.test.ts +307 -0
  376. package/Tests/Server/Services/AuditLogService.test.ts +1124 -0
  377. package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +200 -1
  378. package/Tests/Server/Services/BillingInvoiceServiceMutexRelease.test.ts +254 -0
  379. package/Tests/Server/Services/BillingService.test.ts +70 -0
  380. package/Tests/Server/Services/BillingServicePayInvoiceStates.test.ts +723 -0
  381. package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +14 -2
  382. package/Tests/Server/Services/BillingServiceSubscriptionPaymentMethodSync.test.ts +1634 -0
  383. package/Tests/Server/Services/DatabaseServiceAuditRelationDiff.test.ts +492 -0
  384. package/Tests/Server/Services/DatabaseServicePasswordFieldSecrets.test.ts +629 -0
  385. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +431 -0
  386. package/Tests/Server/Services/IncidentAlertSloReferenceGuard.test.ts +358 -0
  387. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
  388. package/Tests/Server/Services/MonitorProbeServicePastDueMonitoring.test.ts +362 -0
  389. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1460 -1
  390. package/Tests/Server/Services/NetworkDeviceDiagnosticService.test.ts +962 -0
  391. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +106 -0
  392. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +10 -1
  393. package/Tests/Server/Services/NetworkDeviceServicePastDueMonitoring.test.ts +335 -0
  394. package/Tests/Server/Services/NetworkDeviceSiteRuleDnsName.test.ts +568 -0
  395. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  396. package/Tests/Server/Services/ProjectDataResidencyPostgres.test.ts +344 -0
  397. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +187 -0
  398. package/Tests/Server/Services/ProjectServiceDataResidency.test.ts +369 -0
  399. package/Tests/Server/Services/ProjectServiceDataResidencySelfHosted.test.ts +176 -0
  400. package/Tests/Server/Services/ProjectServicePastDueMonitoring.test.ts +289 -0
  401. package/Tests/Server/Services/ResourceFeedServices.test.ts +24 -8
  402. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +1396 -0
  403. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupARun.test.ts +917 -0
  404. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +1262 -0
  405. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +902 -0
  406. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +1163 -0
  407. package/Tests/Server/Services/RuleRun/PrivacyRuleEnginesRun.test.ts +843 -0
  408. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +465 -0
  409. package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1754 -0
  410. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +77 -23
  411. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleFeedWrites.test.ts +777 -0
  412. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleOptions.test.ts +1399 -0
  413. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +67 -74
  414. package/Tests/Server/Services/ServiceLevelObjectiveChildRowTenancy.test.ts +906 -0
  415. package/Tests/Server/Services/ServiceLevelObjectiveDeleteTenancy.test.ts +1029 -0
  416. package/Tests/Server/Services/ServiceLevelObjectiveFeedService.test.ts +313 -0
  417. package/Tests/Server/Services/ServiceLevelObjectiveFeedWrites.test.ts +1214 -0
  418. package/Tests/Server/Services/ServiceLevelObjectiveMarkdownLink.test.ts +289 -0
  419. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +1455 -430
  420. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleLegacyLabelAdoption.test.ts +634 -0
  421. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +1193 -0
  422. package/Tests/Server/Services/{SloMonitorLabelRuleHooks.test.ts → ServiceLevelObjectiveMonitorRuleTriggers.test.ts} +135 -41
  423. package/Tests/Server/Services/ServiceLevelObjectiveOwnerFeedWrites.test.ts +671 -0
  424. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +180 -85
  425. package/Tests/Server/Services/ServiceLevelObjectiveServiceArchive.test.ts +537 -0
  426. package/Tests/Server/Services/ServiceLevelObjectiveServiceLegacyMonitorLabelWrite.test.ts +870 -0
  427. package/Tests/Server/Services/ServiceLevelObjectiveServiceMonitorRuleGuard.test.ts +343 -0
  428. package/Tests/Server/Services/ServiceLevelObjectiveServiceReEvaluation.test.ts +246 -0
  429. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +501 -0
  430. package/Tests/Server/Services/SloAffectedResourceLinkContract.test.ts +86 -0
  431. package/Tests/Server/Services/SloAffectedResourceMetricAttributes.test.ts +547 -0
  432. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +10 -4
  433. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +7 -2
  434. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +174 -0
  435. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateServiceVariables.test.ts +40 -0
  436. package/Tests/Server/Services/SubscriberUpdateNotificationHooks.test.ts +541 -0
  437. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
  438. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
  439. package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
  440. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +288 -0
  441. package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
  442. package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
  443. package/Tests/Server/TestingUtils/PastDueMonitoringClaimSql.ts +177 -0
  444. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +51 -10
  445. package/Tests/Server/TestingUtils/__mocks__/Stripe.mock.ts +16 -1
  446. package/Tests/Server/Types/Database/Permissions/ProjectDataResidencyColumn.test.ts +386 -0
  447. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +34 -11
  448. package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
  449. package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
  450. package/Tests/Server/Utils/AI/SloAffectedResourceAIContext.test.ts +445 -0
  451. package/Tests/Server/Utils/AI/SloTools.test.ts +423 -1
  452. package/Tests/Server/Utils/AI/SloToolsArchive.test.ts +294 -0
  453. package/Tests/Server/Utils/AI/SloToolsRuleReadPermissions.test.ts +297 -0
  454. package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
  455. package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
  456. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
  457. package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
  458. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +255 -10
  459. package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +404 -750
  460. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +45 -0
  461. package/Tests/Server/Utils/Database/RelationValueUtil.test.ts +157 -0
  462. package/Tests/Server/Utils/Monitor/Criteria/BooleanSeriesEvaluateOverTime.test.ts +260 -0
  463. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +181 -0
  464. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +147 -30
  465. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
  466. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.test.ts +17 -0
  467. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +136 -0
  468. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidatorLoadOrder.test.ts +472 -0
  469. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +48 -2
  470. package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +435 -475
  471. package/Tests/Server/Utils/Rules/MonitorRulePatternValidator.test.ts +77 -0
  472. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +177 -0
  473. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +365 -0
  474. package/Tests/Server/Utils/Rules/RuleRun/RuleRunRegistry.test.ts +173 -0
  475. package/Tests/Server/Utils/Rules/RuleRun/RuleRunner.test.ts +675 -0
  476. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +8 -8
  477. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
  478. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
  479. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorFetchSummary.test.ts +261 -0
  480. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1184 -0
  481. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
  482. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
  483. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
  484. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
  485. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsAuth.test.ts → Connectors/GoogleSecOps/GoogleSecOpsAuth.test.ts} +5 -5
  486. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClient.test.ts → Connectors/GoogleSecOps/GoogleSecOpsClient.test.ts} +9 -5
  487. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.test.ts +483 -0
  488. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorCuratedAndLateAlerts.test.ts +676 -0
  489. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFetchEvents.test.ts +1994 -0
  490. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFixtures.ts +332 -0
  491. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorHttpIntegration.test.ts +680 -0
  492. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorRequestContract.test.ts +1206 -0
  493. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorTestConnection.test.ts +1136 -0
  494. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsCuratedRuleCounts.test.ts +407 -0
  495. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsErrorHandling.test.ts → Connectors/GoogleSecOps/GoogleSecOpsErrorHandling.test.ts} +5 -5
  496. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingAdaptiveCatchUp.test.ts +730 -0
  497. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClickhouseIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts} +130 -35
  498. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFailureTaxonomy.test.ts +772 -0
  499. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFixtures.ts +648 -0
  500. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsHttpIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingHttpIntegration.test.ts} +249 -222
  501. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingIntegration.test.ts +1390 -0
  502. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingLoop.test.ts +981 -0
  503. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingNothingImportedRegression.test.ts +290 -0
  504. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsRequestContract.test.ts → Connectors/GoogleSecOps/GoogleSecOpsRequestContract.test.ts} +2 -2
  505. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsResponseParsing.test.ts → Connectors/GoogleSecOps/GoogleSecOpsResponseParsing.test.ts} +5 -5
  506. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsSearchDetections.test.ts +763 -0
  507. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsTesterIntegration.test.ts +421 -0
  508. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
  509. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
  510. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
  511. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
  512. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
  513. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
  514. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +4483 -0
  515. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1178 -0
  516. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +1215 -0
  517. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
  518. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
  519. package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
  520. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1966 -179
  521. package/Tests/Server/Utils/Slo/SloFeedUtil.test.ts +326 -0
  522. package/Tests/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.test.ts +260 -0
  523. package/Tests/Server/Utils/Slo/SloMetricUtil.test.ts +592 -0
  524. package/Tests/Server/Utils/Slo/SloRecordReferenceValidator.test.ts +311 -0
  525. package/Tests/Server/Utils/StatusPageResource.test.ts +91 -3
  526. package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
  527. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
  528. package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
  529. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +348 -2
  530. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
  531. package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
  532. package/Tests/Types/Billing/SubscriptionStatus.test.ts +176 -0
  533. package/Tests/Types/Billing/SubscriptionStatusPastDueMonitoring.test.ts +187 -0
  534. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +53 -7
  535. package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +816 -792
  536. package/Tests/Types/Monitor/CriteriaFilter.test.ts +216 -24
  537. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +14 -1
  538. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +14 -1
  539. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +14 -1
  540. package/Tests/Types/Monitor/MonitorStepRetriesParsing.test.ts +201 -0
  541. package/Tests/Types/Rules/RuleRun.test.ts +315 -0
  542. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +133 -0
  543. package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
  544. package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
  545. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +339 -0
  546. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +217 -0
  547. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +200 -0
  548. package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
  549. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
  550. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
  551. package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +411 -0
  552. package/Tests/UI/Components/AlertBanner.test.tsx +319 -0
  553. package/Tests/UI/Components/BulkArchiveActionsCopy.test.tsx +310 -0
  554. package/Tests/UI/Components/Card.test.tsx +312 -1
  555. package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
  556. package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
  557. package/Tests/UI/Components/Checkbox.test.tsx +79 -0
  558. package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
  559. package/Tests/UI/Components/Detail/DetailIdIsUnique.test.tsx +87 -0
  560. package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
  561. package/Tests/UI/Components/Dropdown/DropdownClearable.test.tsx +393 -0
  562. package/Tests/UI/Components/Dropdown/DropdownMultiSelectChipAccessibleName.test.tsx +64 -0
  563. package/Tests/UI/Components/EmptyState/EmptyState.test.tsx +335 -4
  564. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +337 -0
  565. package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
  566. package/Tests/UI/Components/FacetSections.test.tsx +581 -0
  567. package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
  568. package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
  569. package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +21 -20
  570. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +15 -2
  571. package/Tests/UI/Components/LockedFilterChip.test.tsx +788 -0
  572. package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
  573. package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
  574. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
  575. package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
  576. package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
  577. package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
  578. package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
  579. package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
  580. package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
  581. package/Tests/UI/Components/MoreMenu.test.tsx +133 -0
  582. package/Tests/UI/Components/MoreMenuMotion.test.tsx +84 -3
  583. package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
  584. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
  585. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  586. package/Tests/UI/Components/RuleRun/RuleDetailFields.test.tsx +336 -0
  587. package/Tests/UI/Components/RuleRun/RuleTable.test.tsx +304 -0
  588. package/Tests/UI/Components/RuleRun/RunRuleNowModal.test.tsx +231 -0
  589. package/Tests/UI/Components/RuleRun/RunRulesBulkAction.test.ts +213 -0
  590. package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
  591. package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
  592. package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +367 -0
  593. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
  594. package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
  595. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
  596. package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
  597. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
  598. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
  599. package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
  600. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
  601. package/Tests/UI/Rum/ReplayEngine.test.ts +154 -0
  602. package/Tests/UI/Rum/ReplayHeader.test.tsx +284 -124
  603. package/Tests/UI/Rum/ReplayPinControl.test.tsx +189 -10
  604. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +286 -12
  605. package/Tests/UI/Rum/ReplayRail.test.tsx +294 -0
  606. package/Tests/UI/Rum/ReplayScrubber.test.tsx +213 -1
  607. package/Tests/UI/Rum/ReplayStage.test.tsx +1228 -173
  608. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +433 -3
  609. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +1391 -0
  610. package/Tests/UI/Rum/ReplayTimeline.test.tsx +222 -0
  611. package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
  612. package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
  613. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
  614. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
  615. package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
  616. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
  617. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
  618. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
  619. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
  620. package/Tests/UI/Utils/Clipboard.test.ts +154 -0
  621. package/Tests/UI/Utils/DashboardStackingLayers.test.ts +8 -1
  622. package/Tests/UI/Utils/Navigation.test.ts +24 -0
  623. package/Tests/UI/Utils/RuleRunClient.test.ts +303 -0
  624. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2206 -0
  625. package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
  626. package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
  627. package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
  628. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +2 -0
  629. package/Tests/Utils/Dashboard/Components/DashboardSloListComponent.test.ts +206 -0
  630. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +36 -2
  631. package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +409 -588
  632. package/Tests/Utils/Dashboard/SloWidgetSource.test.ts +351 -0
  633. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +361 -0
  634. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +1425 -118
  635. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +188 -3
  636. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +661 -13
  637. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +349 -0
  638. package/Tests/Utils/NetworkDiscovery/RunImportedDeviceNaming.test.ts +656 -0
  639. package/Tests/Utils/NetworkDiscovery/ShortDeviceNamePlanner.test.ts +1020 -0
  640. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +619 -0
  641. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +317 -0
  642. package/Tests/Utils/Project/DataResidency.test.ts +198 -0
  643. package/Tests/Utils/Rules/RuleRunSummary.test.ts +394 -0
  644. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
  645. package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
  646. package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
  647. package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
  648. package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
  649. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
  650. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
  651. package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
  652. package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
  653. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
  654. package/Tests/Utils/Slo/SloAffectedResourceMarkdown.test.ts +302 -0
  655. package/Tests/Utils/Slo/SloBurnRateTemplate.test.ts +468 -0
  656. package/Tests/Utils/Slo/SloEvaluation.test.ts +20 -4
  657. package/Tests/Utils/Slo/SloFeedMarkdown.test.ts +1185 -0
  658. package/Tests/Utils/Slo/SloHealth.test.ts +262 -0
  659. package/Tests/Utils/Slo/SloHistoryMetricName.test.ts +102 -0
  660. package/Tests/Utils/Slo/SloListWidgetFormat.test.ts +522 -0
  661. package/Tests/Utils/Slo/SloMetricType.test.ts +355 -0
  662. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +387 -0
  663. package/Tests/Utils/Slo/SloMonitorStatusSummary.test.ts +210 -0
  664. package/Tests/Utils/Slo/SloOverviewText.test.ts +226 -0
  665. package/Tests/Utils/Slo/SloProjection.test.ts +1039 -0
  666. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +47 -0
  667. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
  668. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
  669. package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +521 -0
  670. package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
  671. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
  672. package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
  673. package/Types/AI/AIChatTypes.ts +8 -0
  674. package/Types/AI/InvestigationEvidence.ts +96 -0
  675. package/Types/BaseDatabase/EnableAuditLogOn.ts +41 -0
  676. package/Types/Billing/SubscriptionStatus.ts +39 -4
  677. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  678. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +5 -0
  679. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +10 -0
  680. package/Types/Dashboard/DashboardComponents/DashboardSloListComponent.ts +29 -0
  681. package/Types/Dashboard/DashboardTemplates.ts +290 -297
  682. package/Types/Database/EnableAuditLog.ts +23 -1
  683. package/Types/Email/EmailTemplateType.ts +4 -0
  684. package/Types/Monitor/CriteriaFilter.ts +55 -8
  685. package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
  686. package/Types/Monitor/MonitorStep.ts +5 -2
  687. package/Types/Monitor/MonitorStepDnsMonitor.ts +3 -1
  688. package/Types/Monitor/MonitorStepDnssecMonitor.ts +3 -1
  689. package/Types/Monitor/MonitorStepDomainMonitor.ts +3 -1
  690. package/Types/Monitor/MonitorStepExternalStatusPageMonitor.ts +3 -1
  691. package/Types/Monitor/MonitorStepRetries.ts +59 -0
  692. package/Types/Monitor/MonitorStepSnmpMonitor.ts +9 -2
  693. package/Types/NetworkDevice/NetworkDeviceDiagnosticResult.ts +104 -0
  694. package/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.ts +47 -0
  695. package/Types/NetworkDevice/NetworkDeviceDiagnosticType.ts +47 -0
  696. package/Types/NetworkDevice/NetworkDevicePingMetricNames.ts +20 -0
  697. package/Types/Permission.ts +129 -2
  698. package/Types/Rules/RuleCriteriaFieldRegistry.ts +5 -0
  699. package/Types/Rules/RuleRun.ts +518 -0
  700. package/Types/Rum/SessionReplay.ts +109 -0
  701. package/Types/Rum/SessionReplayApi.ts +49 -0
  702. package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +117 -0
  703. package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +113 -0
  704. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +599 -0
  705. package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +45 -0
  706. package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
  707. package/Types/ServiceLevelObjective/SloHistoryMetricName.ts +25 -0
  708. package/Types/ServiceLevelObjective/SloMetricType.ts +49 -0
  709. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +4 -0
  710. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +331 -0
  711. package/Types/StatusPage/SubscriberNotificationTrigger.ts +12 -0
  712. package/Types/StatusPage/SubscriberUpdateNotification.ts +89 -0
  713. package/Types/Telemetry/EntityType.ts +14 -0
  714. package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
  715. package/Types/Telemetry/LockedFilterDetail.ts +25 -0
  716. package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
  717. package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
  718. package/Types/Telemetry/ServiceType.ts +7 -0
  719. package/Typings/Index.d.ts +53 -3
  720. package/UI/Components/AlertBanner/AlertBanner.tsx +85 -27
  721. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +21 -2
  722. package/UI/Components/Card/Card.tsx +118 -83
  723. package/UI/Components/Checkbox/Checkbox.tsx +8 -5
  724. package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
  725. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
  726. package/UI/Components/Detail/Detail.tsx +145 -23
  727. package/UI/Components/Dropdown/Dropdown.tsx +64 -1
  728. package/UI/Components/EmptyState/EmptyState.tsx +27 -3
  729. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +124 -0
  730. package/UI/Components/ErrorBoundary.tsx +38 -0
  731. package/UI/Components/Forms/ModelForm.tsx +6 -5
  732. package/UI/Components/LabelRule/LabelRuleTable.tsx +8 -2
  733. package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
  734. package/UI/Components/LogsViewer/LogsViewer.tsx +152 -77
  735. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +17 -11
  736. package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
  737. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
  738. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
  739. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
  740. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
  741. package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
  742. package/UI/Components/LogsViewer/types.ts +6 -0
  743. package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
  744. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
  745. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
  746. package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
  747. package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
  748. package/UI/Components/ModelList/ModelList.tsx +33 -8
  749. package/UI/Components/MoreMenu/MoreMenu.tsx +14 -3
  750. package/UI/Components/Page/ModelPage.tsx +119 -54
  751. package/UI/Components/RuleRun/RuleDetailFields.tsx +359 -0
  752. package/UI/Components/RuleRun/RuleTable.tsx +183 -0
  753. package/UI/Components/RuleRun/RuleView.tsx +170 -0
  754. package/UI/Components/RuleRun/RunRuleNowModal.tsx +147 -0
  755. package/UI/Components/RuleRun/RunRulesBulkAction.ts +103 -0
  756. package/UI/Components/Table/Table.tsx +8 -0
  757. package/UI/Components/Table/TableRow.tsx +13 -5
  758. package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
  759. package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
  760. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +7 -0
  761. package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
  762. package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
  763. package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
  764. package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
  765. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +430 -0
  766. package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +14 -10
  767. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
  768. package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
  769. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
  770. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
  771. package/UI/Components/TelemetryViewer/types.ts +19 -0
  772. package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
  773. package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
  774. package/UI/Utils/Clipboard.ts +68 -2
  775. package/UI/Utils/Navigation.ts +17 -2
  776. package/UI/Utils/Rules/RuleRunClient.ts +178 -0
  777. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +628 -0
  778. package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
  779. package/Utils/AI/InvestigationReport.ts +1789 -0
  780. package/Utils/API.ts +90 -1
  781. package/Utils/Dashboard/Components/DashboardSloComponent.ts +19 -2
  782. package/Utils/Dashboard/Components/DashboardSloListComponent.ts +126 -0
  783. package/Utils/Dashboard/Components/Index.ts +7 -0
  784. package/Utils/Dashboard/SloWidgetSource.ts +188 -0
  785. package/Utils/Markdown/MarkdownEscape.ts +63 -0
  786. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +161 -36
  787. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +25 -0
  788. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +146 -0
  789. package/Utils/NetworkDiscovery/RunImportedDeviceNaming.ts +390 -0
  790. package/Utils/NetworkDiscovery/ShortDeviceNamePlanner.ts +291 -0
  791. package/Utils/NetworkDiscovery/ShortHostnameUtil.ts +91 -0
  792. package/Utils/NetworkSite/CidrMatchUtil.ts +37 -12
  793. package/Utils/Project/DataResidency.ts +63 -0
  794. package/Utils/Rules/RuleRunSummary.ts +323 -0
  795. package/Utils/Rum/SessionReplayHealth.ts +11 -0
  796. package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
  797. package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
  798. package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
  799. package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
  800. package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
  801. package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
  802. package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
  803. package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
  804. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
  805. package/Utils/Slo/SloAffectedResourceMarkdown.ts +123 -0
  806. package/Utils/Slo/SloBurnRateTemplate.ts +373 -0
  807. package/Utils/Slo/SloFeedMarkdown.ts +1507 -0
  808. package/Utils/Slo/SloHealth.ts +96 -9
  809. package/Utils/Slo/SloListWidgetFormat.ts +370 -0
  810. package/Utils/Slo/SloMetricType.ts +237 -0
  811. package/Utils/Slo/SloMonitorRuleCriteria.ts +364 -0
  812. package/Utils/Slo/SloMonitorStatusSummary.ts +210 -0
  813. package/Utils/Slo/SloOverviewText.ts +265 -0
  814. package/Utils/Slo/SloProjection.ts +967 -0
  815. package/Utils/Slo/SloWidgetFormat.ts +12 -2
  816. package/Utils/Telemetry/CrossSignalScope.ts +22 -8
  817. package/Utils/Telemetry/EntityRelationship.ts +8 -0
  818. package/Utils/Telemetry/LockedFilterSearch.ts +366 -0
  819. package/Utils/Telemetry/NetworkHost.ts +43 -0
  820. package/Utils/Telemetry/OriginAllowList.ts +139 -4
  821. package/Utils/Traces/CriticalPath.ts +10 -4
  822. package/build/dist/Models/AnalyticsModels/AuditLog.js +70 -1
  823. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  824. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +4 -4
  825. package/build/dist/Models/DatabaseModels/Alert.js +60 -0
  826. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  827. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  828. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  829. package/build/dist/Models/DatabaseModels/Incident.js +64 -0
  830. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  831. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +75 -0
  832. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  833. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +75 -0
  834. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  835. package/build/dist/Models/DatabaseModels/Index.js +10 -4
  836. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  837. package/build/dist/Models/DatabaseModels/NetworkDevice.js +68 -0
  838. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  839. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js +772 -0
  840. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js.map +1 -0
  841. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +140 -0
  842. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  843. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +1 -1
  844. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
  845. package/build/dist/Models/DatabaseModels/Project.js +42 -0
  846. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  847. package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
  848. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  849. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +75 -0
  850. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  851. package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnection.js → SecurityEventConnection.js} +87 -75
  852. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
  853. package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnectionRun.js → SecurityEventConnectionRun.js} +37 -37
  854. package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
  855. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +192 -10
  856. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  857. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +798 -96
  858. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
  859. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +596 -0
  860. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -0
  861. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +590 -0
  862. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -0
  863. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +16 -0
  864. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
  865. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +16 -0
  866. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
  867. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +75 -0
  868. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  869. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
  870. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  871. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +1 -1
  872. package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
  873. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  874. package/build/dist/Server/API/BaseAPI.js +14 -0
  875. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  876. package/build/dist/Server/API/BillingInvoiceAPI.js +233 -19
  877. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  878. package/build/dist/Server/API/BillingPaymentMethodAPI.js +86 -5
  879. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  880. package/build/dist/Server/API/DashboardAPI.js +72 -2
  881. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  882. package/build/dist/Server/API/SecurityEventConnectionAPI.js +263 -0
  883. package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
  884. package/build/dist/Server/API/StatusPageAPI.js +236 -154
  885. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  886. package/build/dist/Server/API/TelemetryAPI.js +248 -170
  887. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  888. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
  889. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
  890. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js +34 -0
  891. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js.map +1 -0
  892. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js +24 -0
  893. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js.map +1 -0
  894. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js +21 -0
  895. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js.map +1 -0
  896. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js +207 -0
  897. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js.map +1 -0
  898. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js +72 -0
  899. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js.map +1 -0
  900. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js +20 -0
  901. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js.map +1 -0
  902. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js +46 -0
  903. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js.map +1 -0
  904. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
  905. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  906. package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
  907. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  908. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +112 -56
  909. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  910. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +167 -68
  911. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  912. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +87 -26
  913. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  914. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +270 -203
  915. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  916. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +498 -354
  917. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  918. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +97 -34
  919. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  920. package/build/dist/Server/Services/AlertService.js +91 -8
  921. package/build/dist/Server/Services/AlertService.js.map +1 -1
  922. package/build/dist/Server/Services/AuditLogService.js +408 -44
  923. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  924. package/build/dist/Server/Services/BillingInvoiceService.js +94 -85
  925. package/build/dist/Server/Services/BillingInvoiceService.js.map +1 -1
  926. package/build/dist/Server/Services/BillingService.js +406 -14
  927. package/build/dist/Server/Services/BillingService.js.map +1 -1
  928. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +141 -92
  929. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  930. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +189 -101
  931. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  932. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +135 -86
  933. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  934. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +189 -100
  935. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  936. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +117 -69
  937. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  938. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +171 -83
  939. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  940. package/build/dist/Server/Services/DatabaseService.js +125 -18
  941. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  942. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +141 -92
  943. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  944. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +189 -101
  945. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  946. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +145 -91
  947. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  948. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +191 -101
  949. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  950. package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
  951. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  952. package/build/dist/Server/Services/HostLabelRuleEngineService.js +141 -92
  953. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  954. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +190 -102
  955. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  956. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +112 -56
  957. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  958. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +220 -63
  959. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  960. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +87 -26
  961. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  962. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  963. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  964. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +258 -192
  965. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  966. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +519 -376
  967. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  968. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +95 -32
  969. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  970. package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
  971. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  972. package/build/dist/Server/Services/IncidentService.js +90 -5
  973. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  974. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +113 -65
  975. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  976. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +171 -83
  977. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  978. package/build/dist/Server/Services/Index.js +10 -4
  979. package/build/dist/Server/Services/Index.js.map +1 -1
  980. package/build/dist/Server/Services/InventoryItemService.js +22 -0
  981. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  982. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +117 -69
  983. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  984. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +171 -83
  985. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  986. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +145 -91
  987. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  988. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +191 -101
  989. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  990. package/build/dist/Server/Services/LabelService.js +20 -25
  991. package/build/dist/Server/Services/LabelService.js.map +1 -1
  992. package/build/dist/Server/Services/LogAggregationService.js +8 -17
  993. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  994. package/build/dist/Server/Services/MetricAggregationService.js +4 -14
  995. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  996. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +123 -77
  997. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  998. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +167 -82
  999. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  1000. package/build/dist/Server/Services/MonitorProbeService.js +18 -2
  1001. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  1002. package/build/dist/Server/Services/MonitorService.js +11 -9
  1003. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  1004. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +287 -5
  1005. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  1006. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js +333 -0
  1007. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js.map +1 -0
  1008. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +117 -69
  1009. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  1010. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +171 -83
  1011. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  1012. package/build/dist/Server/Services/NetworkDeviceService.js +36 -2
  1013. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  1014. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +117 -64
  1015. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  1016. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +173 -83
  1017. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  1018. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +116 -65
  1019. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  1020. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +171 -83
  1021. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  1022. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +141 -92
  1023. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  1024. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +189 -101
  1025. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  1026. package/build/dist/Server/Services/ProjectService.js +82 -10
  1027. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  1028. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +141 -92
  1029. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  1030. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +189 -101
  1031. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  1032. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +111 -63
  1033. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  1034. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +161 -77
  1035. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  1036. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +117 -69
  1037. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  1038. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +171 -83
  1039. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  1040. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +280 -209
  1041. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  1042. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +521 -376
  1043. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  1044. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
  1045. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  1046. package/build/dist/Server/Services/ScheduledMaintenanceService.js +24 -8
  1047. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  1048. package/build/dist/Server/Services/{GoogleSecOpsConnectionRunService.js → SecurityEventConnectionRunService.js} +2 -2
  1049. package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
  1050. package/build/dist/Server/Services/SecurityEventConnectionService.js +396 -0
  1051. package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
  1052. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +115 -62
  1053. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  1054. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +163 -77
  1055. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  1056. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +141 -92
  1057. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  1058. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +769 -18
  1059. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
  1060. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js +96 -0
  1061. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js.map +1 -0
  1062. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +614 -87
  1063. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  1064. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +844 -0
  1065. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -0
  1066. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +207 -1
  1067. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -1
  1068. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +221 -1
  1069. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -1
  1070. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +997 -50
  1071. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  1072. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +191 -102
  1073. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  1074. package/build/dist/Server/Services/StatusPageAnnouncementService.js +12 -0
  1075. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  1076. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +118 -70
  1077. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  1078. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +158 -76
  1079. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  1080. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +19 -215
  1081. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  1082. package/build/dist/Server/Services/StatusPageSubscriberService.js +6 -0
  1083. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  1084. package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -5
  1085. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  1086. package/build/dist/Server/Services/ThreatIntelFeedService.js +1 -1
  1087. package/build/dist/Server/Services/TraceAggregationService.js +51 -25
  1088. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  1089. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +141 -92
  1090. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
  1091. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +189 -101
  1092. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  1093. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +117 -69
  1094. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  1095. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +171 -83
  1096. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  1097. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
  1098. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  1099. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +17 -0
  1100. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  1101. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  1102. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  1103. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +31 -0
  1104. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  1105. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
  1106. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  1107. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
  1108. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
  1109. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
  1110. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
  1111. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +24 -1
  1112. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  1113. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +21 -1
  1114. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  1115. package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
  1116. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  1117. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +337 -53
  1118. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  1119. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
  1120. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
  1121. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
  1122. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  1123. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +108 -15
  1124. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  1125. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +2 -2
  1126. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -1
  1127. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +115 -6
  1128. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -1
  1129. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +13 -0
  1130. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  1131. package/build/dist/Server/Utils/Database/RelationValueUtil.js +82 -0
  1132. package/build/dist/Server/Utils/Database/RelationValueUtil.js.map +1 -0
  1133. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +10 -6
  1134. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  1135. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +17 -21
  1136. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  1137. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
  1138. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  1139. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +5 -4
  1140. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  1141. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +50 -10
  1142. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  1143. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +13 -1
  1144. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  1145. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +6 -10
  1146. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  1147. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js +34 -0
  1148. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js.map +1 -0
  1149. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +69 -0
  1150. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -0
  1151. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js +25 -0
  1152. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js.map +1 -0
  1153. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js +128 -0
  1154. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js.map +1 -0
  1155. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +746 -0
  1156. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -0
  1157. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js +221 -0
  1158. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js.map +1 -0
  1159. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +3 -2
  1160. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
  1161. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
  1162. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
  1163. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
  1164. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
  1165. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +354 -0
  1166. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
  1167. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
  1168. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
  1169. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
  1170. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
  1171. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
  1172. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
  1173. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
  1174. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
  1175. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.js +401 -68
  1176. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  1177. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js +1417 -0
  1178. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js.map +1 -0
  1179. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
  1180. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
  1181. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
  1182. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
  1183. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
  1184. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
  1185. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
  1186. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
  1187. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
  1188. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
  1189. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
  1190. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
  1191. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +839 -0
  1192. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
  1193. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.js → Connectors/SecurityEventConnectionRunExecutor.js} +77 -50
  1194. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
  1195. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +214 -0
  1196. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
  1197. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +42 -0
  1198. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
  1199. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
  1200. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
  1201. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
  1202. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
  1203. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +122 -0
  1204. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
  1205. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +1 -1
  1206. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
  1207. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
  1208. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +2 -2
  1209. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +599 -32
  1210. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  1211. package/build/dist/Server/Utils/Slo/SloFeedUtil.js +150 -0
  1212. package/build/dist/Server/Utils/Slo/SloFeedUtil.js.map +1 -0
  1213. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js +136 -0
  1214. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js.map +1 -0
  1215. package/build/dist/Server/Utils/Slo/SloMetricUtil.js +269 -0
  1216. package/build/dist/Server/Utils/Slo/SloMetricUtil.js.map +1 -0
  1217. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js +134 -0
  1218. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js.map +1 -0
  1219. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js +137 -0
  1220. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js.map +1 -0
  1221. package/build/dist/Server/Utils/StartServer.js +10 -0
  1222. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  1223. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +6 -26
  1224. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -1
  1225. package/build/dist/Server/Utils/StatusPageResource.js +31 -5
  1226. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  1227. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
  1228. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  1229. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
  1230. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
  1231. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
  1232. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  1233. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
  1234. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
  1235. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
  1236. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  1237. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
  1238. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
  1239. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
  1240. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
  1241. package/build/dist/Server/Utils/Telemetry.js +11 -5
  1242. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  1243. package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
  1244. package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
  1245. package/build/dist/Types/Billing/SubscriptionStatus.js +37 -3
  1246. package/build/dist/Types/Billing/SubscriptionStatus.js.map +1 -1
  1247. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  1248. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  1249. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +5 -0
  1250. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  1251. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js +2 -0
  1252. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js.map +1 -0
  1253. package/build/dist/Types/Dashboard/DashboardTemplates.js +275 -286
  1254. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  1255. package/build/dist/Types/Database/EnableAuditLog.js +19 -1
  1256. package/build/dist/Types/Database/EnableAuditLog.js.map +1 -1
  1257. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  1258. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  1259. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -6
  1260. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  1261. package/build/dist/Types/Monitor/MonitorStep.js +2 -0
  1262. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  1263. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js +3 -1
  1264. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js.map +1 -1
  1265. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +3 -1
  1266. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -1
  1267. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +3 -1
  1268. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  1269. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js +3 -1
  1270. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js.map +1 -1
  1271. package/build/dist/Types/Monitor/MonitorStepRetries.js +47 -0
  1272. package/build/dist/Types/Monitor/MonitorStepRetries.js.map +1 -0
  1273. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -1
  1274. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
  1275. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js +29 -0
  1276. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js.map +1 -0
  1277. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js +37 -0
  1278. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js.map +1 -0
  1279. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js +42 -0
  1280. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js.map +1 -0
  1281. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js +20 -0
  1282. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js.map +1 -0
  1283. package/build/dist/Types/Permission.js +116 -2
  1284. package/build/dist/Types/Permission.js.map +1 -1
  1285. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +5 -0
  1286. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  1287. package/build/dist/Types/Rules/RuleRun.js +267 -0
  1288. package/build/dist/Types/Rules/RuleRun.js.map +1 -0
  1289. package/build/dist/Types/Rum/SessionReplay.js +95 -0
  1290. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  1291. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  1292. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
  1293. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
  1294. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +17 -0
  1295. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
  1296. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +439 -0
  1297. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
  1298. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +39 -0
  1299. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
  1300. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
  1301. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
  1302. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js +26 -0
  1303. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js.map +1 -0
  1304. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js +45 -0
  1305. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js.map +1 -0
  1306. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
  1307. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  1308. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +295 -0
  1309. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -0
  1310. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js +13 -0
  1311. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js.map +1 -0
  1312. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +67 -0
  1313. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -0
  1314. package/build/dist/Types/Telemetry/EntityType.js +14 -0
  1315. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  1316. package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
  1317. package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
  1318. package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
  1319. package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
  1320. package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
  1321. package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
  1322. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
  1323. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
  1324. package/build/dist/Types/Telemetry/ServiceType.js +7 -0
  1325. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  1326. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +48 -19
  1327. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
  1328. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +10 -2
  1329. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  1330. package/build/dist/UI/Components/Card/Card.js +34 -17
  1331. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  1332. package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
  1333. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  1334. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  1335. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  1336. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
  1337. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  1338. package/build/dist/UI/Components/Detail/Detail.js +74 -15
  1339. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  1340. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -5
  1341. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  1342. package/build/dist/UI/Components/EmptyState/EmptyState.js +3 -3
  1343. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  1344. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +47 -0
  1345. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +1 -0
  1346. package/build/dist/UI/Components/ErrorBoundary.js +34 -0
  1347. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  1348. package/build/dist/UI/Components/Forms/ModelForm.js +6 -5
  1349. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  1350. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +6 -2
  1351. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -1
  1352. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
  1353. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
  1354. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
  1355. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  1356. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +3 -7
  1357. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  1358. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
  1359. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
  1360. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
  1361. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  1362. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
  1363. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  1364. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
  1365. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  1366. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
  1367. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  1368. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
  1369. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  1370. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  1371. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
  1372. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
  1373. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
  1374. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  1375. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
  1376. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  1377. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
  1378. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  1379. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
  1380. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  1381. package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
  1382. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  1383. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +3 -1
  1384. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  1385. package/build/dist/UI/Components/Page/ModelPage.js +62 -34
  1386. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  1387. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js +226 -0
  1388. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js.map +1 -0
  1389. package/build/dist/UI/Components/RuleRun/RuleTable.js +97 -0
  1390. package/build/dist/UI/Components/RuleRun/RuleTable.js.map +1 -0
  1391. package/build/dist/UI/Components/RuleRun/RuleView.js +83 -0
  1392. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -0
  1393. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +74 -0
  1394. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -0
  1395. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js +78 -0
  1396. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js.map +1 -0
  1397. package/build/dist/UI/Components/Table/Table.js +3 -1
  1398. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  1399. package/build/dist/UI/Components/Table/TableRow.js +8 -1
  1400. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  1401. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
  1402. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
  1403. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
  1404. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
  1405. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  1406. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  1407. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
  1408. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
  1409. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
  1410. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
  1411. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
  1412. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
  1413. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
  1414. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
  1415. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +202 -0
  1416. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
  1417. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +2 -6
  1418. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
  1419. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
  1420. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  1421. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
  1422. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
  1423. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
  1424. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  1425. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
  1426. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  1427. package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
  1428. package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
  1429. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
  1430. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
  1431. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
  1432. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
  1433. package/build/dist/UI/Utils/Clipboard.js +59 -2
  1434. package/build/dist/UI/Utils/Clipboard.js.map +1 -1
  1435. package/build/dist/UI/Utils/Navigation.js +11 -2
  1436. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  1437. package/build/dist/UI/Utils/Rules/RuleRunClient.js +98 -0
  1438. package/build/dist/UI/Utils/Rules/RuleRunClient.js.map +1 -0
  1439. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +479 -0
  1440. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
  1441. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
  1442. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
  1443. package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
  1444. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
  1445. package/build/dist/Utils/API.js +25 -0
  1446. package/build/dist/Utils/API.js.map +1 -1
  1447. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +16 -2
  1448. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -1
  1449. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js +94 -0
  1450. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js.map +1 -0
  1451. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  1452. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  1453. package/build/dist/Utils/Dashboard/SloWidgetSource.js +125 -0
  1454. package/build/dist/Utils/Dashboard/SloWidgetSource.js.map +1 -0
  1455. package/build/dist/Utils/Markdown/MarkdownEscape.js +49 -0
  1456. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -0
  1457. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +112 -34
  1458. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1459. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +22 -0
  1460. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  1461. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +129 -0
  1462. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -0
  1463. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js +255 -0
  1464. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js.map +1 -0
  1465. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js +184 -0
  1466. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js.map +1 -0
  1467. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js +79 -0
  1468. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js.map +1 -0
  1469. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +21 -12
  1470. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
  1471. package/build/dist/Utils/Project/DataResidency.js +51 -0
  1472. package/build/dist/Utils/Project/DataResidency.js.map +1 -0
  1473. package/build/dist/Utils/Rules/RuleRunSummary.js +197 -0
  1474. package/build/dist/Utils/Rules/RuleRunSummary.js.map +1 -0
  1475. package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
  1476. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
  1477. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
  1478. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
  1479. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
  1480. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
  1481. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
  1482. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
  1483. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
  1484. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
  1485. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
  1486. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
  1487. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
  1488. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
  1489. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
  1490. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
  1491. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
  1492. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
  1493. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
  1494. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  1495. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js +51 -0
  1496. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js.map +1 -0
  1497. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +228 -0
  1498. package/build/dist/Utils/Slo/SloBurnRateTemplate.js.map +1 -0
  1499. package/build/dist/Utils/Slo/SloFeedMarkdown.js +934 -0
  1500. package/build/dist/Utils/Slo/SloFeedMarkdown.js.map +1 -0
  1501. package/build/dist/Utils/Slo/SloHealth.js +75 -9
  1502. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1503. package/build/dist/Utils/Slo/SloListWidgetFormat.js +217 -0
  1504. package/build/dist/Utils/Slo/SloListWidgetFormat.js.map +1 -0
  1505. package/build/dist/Utils/Slo/SloMetricType.js +212 -0
  1506. package/build/dist/Utils/Slo/SloMetricType.js.map +1 -0
  1507. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +216 -0
  1508. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -0
  1509. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js +129 -0
  1510. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js.map +1 -0
  1511. package/build/dist/Utils/Slo/SloOverviewText.js +110 -0
  1512. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -0
  1513. package/build/dist/Utils/Slo/SloProjection.js +448 -0
  1514. package/build/dist/Utils/Slo/SloProjection.js.map +1 -0
  1515. package/build/dist/Utils/Slo/SloWidgetFormat.js +4 -2
  1516. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -1
  1517. package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
  1518. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  1519. package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
  1520. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  1521. package/build/dist/Utils/Telemetry/LockedFilterSearch.js +252 -0
  1522. package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
  1523. package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
  1524. package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
  1525. package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
  1526. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
  1527. package/build/dist/Utils/Traces/CriticalPath.js +9 -4
  1528. package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
  1529. package/package.json +1 -1
  1530. package/Server/API/GoogleSecOpsConnectionAPI.ts +0 -79
  1531. package/Server/Services/GoogleSecOpsConnectionService.ts +0 -101
  1532. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +0 -774
  1533. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +0 -423
  1534. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +0 -724
  1535. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +0 -248
  1536. package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +0 -153
  1537. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +0 -711
  1538. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +0 -838
  1539. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +0 -716
  1540. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +0 -860
  1541. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +0 -1231
  1542. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
  1543. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +0 -56
  1544. package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
  1545. package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
  1546. package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
  1547. package/UI/Components/GanttChart/Index.tsx +0 -90
  1548. package/UI/Components/GanttChart/Row/Index.tsx +0 -22
  1549. package/UI/Components/GanttChart/Row/Row.tsx +0 -231
  1550. package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
  1551. package/UI/Components/GanttChart/Rows.tsx +0 -59
  1552. package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
  1553. package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
  1554. package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
  1555. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +0 -1
  1556. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +0 -1
  1557. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +0 -56
  1558. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +0 -1
  1559. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +0 -1
  1560. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +0 -62
  1561. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +0 -1
  1562. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +0 -1
  1563. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +0 -577
  1564. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +0 -1
  1565. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +0 -1
  1566. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +0 -2
  1567. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +0 -1
  1568. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
  1569. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
  1570. package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
  1571. package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
  1572. package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
  1573. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
  1574. package/build/dist/UI/Components/GanttChart/Index.js +0 -39
  1575. package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
  1576. package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
  1577. package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
  1578. package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
  1579. package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
  1580. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
  1581. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
  1582. package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
  1583. package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
  1584. package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
  1585. package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
  1586. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
  1587. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
  1588. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
  1589. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js.map +0 -1
@@ -13,6 +13,7 @@ import {
13
13
  fireEvent,
14
14
  render,
15
15
  screen,
16
+ within,
16
17
  } from "@testing-library/react";
17
18
  import * as React from "react";
18
19
  import getJestMockFunction, { MockFunction } from "../../MockType";
@@ -30,6 +31,7 @@ const getFriendlyMessageMock: MockFunction = getJestMockFunction();
30
31
  const getCommonHeadersMock: MockFunction = getJestMockFunction();
31
32
  const markdownViewerMock: MockFunction = getJestMockFunction();
32
33
  const activityFeedMock: MockFunction = getJestMockFunction();
34
+ const widgetRendererMock: MockFunction = getJestMockFunction();
33
35
 
34
36
  jest.mock("../../../UI/Utils/API/API", () => {
35
37
  return {
@@ -59,6 +61,8 @@ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
59
61
  /*
60
62
  * Record MarkdownViewer's props so safeMode remains an asserted part of the
61
63
  * contract even when the Common Jest config replaces its markdown renderer.
64
+ * The recorded `inlineReferences` are the panel's own chip/link renderers, so
65
+ * tests can call them and render what they return.
62
66
  */
63
67
  jest.mock("../../../UI/Components/Markdown.tsx/LazyMarkdownViewer", () => {
64
68
  return {
@@ -75,13 +79,30 @@ jest.mock("../../../UI/Components/Markdown.tsx/LazyMarkdownViewer", () => {
75
79
  });
76
80
 
77
81
  /*
78
- * The feed owns the "will this draw any steps?" predicate, because several
79
- * event types only close a step an earlier event opened. The panel asks it
80
- * instead of counting raw events, so the mock has to answer too — and
81
- * hasRenderableActivityMock lets a test make the two disagree, which is the
82
- * case that used to render an empty framed box.
82
+ * The feed owns "how many steps will this draw?", because several event
83
+ * types only close a step an earlier event opened. The panel and its run
84
+ * details ask it instead of counting raw events, so the mock has to answer
85
+ * too. countActivityStepsMock lets a test make events and steps disagree
86
+ * the case that used to frame an empty box — and hasRenderableActivityMock
87
+ * follows it by default, exactly as the real predicate does, so the two
88
+ * exports can never contradict each other unless a test says so.
83
89
  */
84
90
  const hasRenderableActivityMock: MockFunction = getJestMockFunction();
91
+ const countActivityStepsMock: MockFunction = getJestMockFunction();
92
+
93
+ // Evidence rows render through the chat widgets; their output is not under test.
94
+ jest.mock(
95
+ "../../../../App/FeatureSet/Dashboard/src/Components/AIChat/Widgets/WidgetRenderer",
96
+ () => {
97
+ return {
98
+ __esModule: true,
99
+ default: (props: { widgets: Array<JSONObject> }): React.ReactElement => {
100
+ widgetRendererMock(props);
101
+ return React.createElement("div", { "data-testid": "evidence-widget" });
102
+ },
103
+ };
104
+ },
105
+ );
85
106
 
86
107
  jest.mock(
87
108
  "../../../../App/FeatureSet/Dashboard/src/Components/AIChat/ChatActivityFeed",
@@ -97,6 +118,9 @@ jest.mock(
97
118
  hasRenderableActivity: (events: Array<AIRunEvent>): boolean => {
98
119
  return hasRenderableActivityMock(events) as boolean;
99
120
  },
121
+ countActivitySteps: (events: Array<AIRunEvent>): number => {
122
+ return countActivityStepsMock(events) as number;
123
+ },
100
124
  };
101
125
  },
102
126
  );
@@ -108,13 +132,16 @@ import AIRunEvent from "../../../Models/DatabaseModels/AIRunEvent";
108
132
  import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
109
133
  import AIRunCodeFixRecommendation from "../../../Types/AI/AIRunCodeFixRecommendation";
110
134
  import AIRunEventType from "../../../Types/AI/AIRunEventType";
135
+ import AIRunHumanVerdict from "../../../Types/AI/AIRunHumanVerdict";
111
136
  import AIRunStatus from "../../../Types/AI/AIRunStatus";
112
137
  import { JSONArray, JSONObject } from "../../../Types/JSON";
113
138
  import ObjectID from "../../../Types/ObjectID";
139
+ import type { MarkdownInlineReferenceRenderers } from "../../../UI/Components/Markdown.tsx/InlineReferences";
114
140
 
115
141
  interface MarkdownViewerProps {
116
142
  text: string;
117
143
  safeMode?: boolean | undefined;
144
+ inlineReferences?: MarkdownInlineReferenceRenderers | undefined;
118
145
  }
119
146
 
120
147
  interface ActivityFeedProps {
@@ -138,6 +165,8 @@ interface InvestigationPayloadOptions {
138
165
  humanVerdict?: string | null | undefined;
139
166
  codeFixRecommendation?: AIRunCodeFixRecommendation | undefined;
140
167
  completedAt?: string | undefined;
168
+ evidence?: JSONArray | undefined;
169
+ references?: JSONArray | undefined;
141
170
  }
142
171
 
143
172
  interface ApiResponse {
@@ -203,13 +232,27 @@ function investigationPayload(
203
232
  run["completedAt"] = options.completedAt;
204
233
  }
205
234
 
206
- return {
235
+ const payload: JSONObject = {
207
236
  run,
208
237
  events: options.events || [],
209
238
  analysisMarkdown: options.analysisMarkdown ?? null,
210
239
  analysisTldr: options.analysisTldr ?? null,
211
240
  isAnalysisPending: options.isAnalysisPending === true,
212
241
  };
242
+
243
+ /*
244
+ * Older API replicas omit these keys entirely, so they are only present
245
+ * when a test asks for them.
246
+ */
247
+ if (options.evidence !== undefined) {
248
+ payload["evidence"] = options.evidence;
249
+ }
250
+
251
+ if (options.references !== undefined) {
252
+ payload["references"] = options.references;
253
+ }
254
+
255
+ return payload;
213
256
  }
214
257
 
215
258
  function successfulResponse(payload: JSONObject): ApiResponse {
@@ -264,6 +307,8 @@ function renderPanel(data?: {
264
307
  subjectId?: ObjectID | undefined;
265
308
  onAnalysisAvailable?: (() => void) | undefined;
266
309
  onStatusChange?: ((status: AIRunStatus | null) => void) | undefined;
310
+ onReportSummaryChange?: ((summary: string | null) => void) | undefined;
311
+ onVerdictChange?: ((verdict: AIRunHumanVerdict | null) => void) | undefined;
267
312
  }): ReturnType<typeof render> {
268
313
  return render(
269
314
  <InvestigationPanel
@@ -271,6 +316,8 @@ function renderPanel(data?: {
271
316
  subjectId={data?.subjectId || INCIDENT_ID}
272
317
  onAnalysisAvailable={data?.onAnalysisAvailable}
273
318
  onStatusChange={data?.onStatusChange}
319
+ onReportSummaryChange={data?.onReportSummaryChange}
320
+ onVerdictChange={data?.onVerdictChange}
274
321
  />,
275
322
  );
276
323
  }
@@ -334,17 +381,59 @@ function lastActivityProps(): ActivityFeedProps {
334
381
  return calls[calls.length - 1]![0]!;
335
382
  }
336
383
 
384
+ /*
385
+ * A completed run ends with one collapsed section holding its evidence, its
386
+ * activity and what it cost. Its body stays mounted while collapsed, so the
387
+ * role queries below (which skip hidden content) only find what a reader
388
+ * could actually reach; tests open the section before reaching inside it.
389
+ */
390
+ function runDetails(): HTMLElement {
391
+ return screen.getByTestId("investigation-details");
392
+ }
393
+
394
+ function detailsToggle(): HTMLElement {
395
+ return screen.getByTestId("investigation-details-toggle");
396
+ }
397
+
398
+ function detailsBody(): HTMLElement {
399
+ const bodyId: string | null = detailsToggle().getAttribute("aria-controls");
400
+ expect(bodyId).toBeTruthy();
401
+ return document.getElementById(bodyId!)!;
402
+ }
403
+
404
+ function openDetails(): void {
405
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
406
+ fireEvent.click(detailsToggle());
407
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
408
+ }
409
+
410
+ function detailsTab(name: RegExp): HTMLElement {
411
+ return within(
412
+ screen.getByRole("tablist", { name: "Investigation details" }),
413
+ ).getByRole("tab", { name });
414
+ }
415
+
416
+ function evidenceList(): HTMLElement {
417
+ return screen.getByRole("list", { name: "Evidence checked" });
418
+ }
419
+
337
420
  beforeEach(() => {
338
421
  jest.useFakeTimers();
339
422
  jest.setSystemTime(new Date(COMPLETED_AT));
340
423
  getCommonHeadersMock.mockReturnValue({});
341
424
  /*
342
425
  * Default to the real component's behaviour for the ordinary event shapes
343
- * these tests use: every step-opening event draws a step.
426
+ * these tests use: every step-opening event draws a step, and there is
427
+ * activity to render exactly when at least one step is drawn.
344
428
  */
429
+ countActivityStepsMock.mockImplementation(
430
+ (events: Array<AIRunEvent>): number => {
431
+ return events.length;
432
+ },
433
+ );
345
434
  hasRenderableActivityMock.mockImplementation(
346
435
  (events: Array<AIRunEvent>): boolean => {
347
- return events.length > 0;
436
+ return (countActivityStepsMock(events) as number) > 0;
348
437
  },
349
438
  );
350
439
  getFriendlyMessageMock.mockImplementation((error: unknown): string => {
@@ -371,6 +460,8 @@ afterEach(() => {
371
460
  markdownViewerMock.mockReset();
372
461
  activityFeedMock.mockReset();
373
462
  hasRenderableActivityMock.mockReset();
463
+ countActivityStepsMock.mockReset();
464
+ widgetRendererMock.mockReset();
374
465
  });
375
466
 
376
467
  describe("InvestigationPanel report lifecycle", () => {
@@ -420,7 +511,7 @@ describe("InvestigationPanel report lifecycle", () => {
420
511
  expect(getCommonHeadersMock).toHaveBeenCalledTimes(1);
421
512
  });
422
513
 
423
- test("renders the completed report safely and demotes activity to a disclosure", async () => {
514
+ test("renders the completed report safely and folds its activity into a collapsed section", async () => {
424
515
  const onAnalysisAvailable: MockFunction = getJestMockFunction();
425
516
  postMock.mockResolvedValue(completedResponse() as never);
426
517
 
@@ -432,25 +523,45 @@ describe("InvestigationPanel report lifecycle", () => {
432
523
  expect(screen.getByTestId("investigation-markdown")).toHaveTextContent(
433
524
  "The database connection pool was exhausted.",
434
525
  );
526
+ /*
527
+ * The report renders section by section: the "## Root cause" heading
528
+ * becomes the section's own title and its body goes through the safe
529
+ * viewer together with the panel's inline reference renderers.
530
+ */
435
531
  expect(markdownViewerMock).toHaveBeenCalledWith({
436
- text: ANALYSIS,
532
+ text: "The database connection pool was exhausted.",
437
533
  safeMode: true,
534
+ inlineReferences: expect.objectContaining({
535
+ renderCitation: expect.any(Function),
536
+ renderEventReference: expect.any(Function),
537
+ }),
438
538
  });
439
- expect(screen.getByText("Investigation activity")).toBeInTheDocument();
539
+ expect(
540
+ screen.getByRole("heading", { level: 4, name: "Root cause" }),
541
+ ).toBeInTheDocument();
542
+ /*
543
+ * This report carries no evidence, so the section is only the activity
544
+ * and is named for it. It starts collapsed: the report is the answer.
545
+ */
546
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
547
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
548
+ expect(detailsBody()).not.toBeVisible();
440
549
  expect(lastActivityProps()).toEqual(
441
550
  expect.objectContaining({
442
551
  hideChrome: true,
443
552
  showLiveIndicator: false,
444
- maxVisibleSteps: 10,
445
553
  }),
446
554
  );
447
555
 
448
556
  const usage: HTMLElement = screen.getByLabelText("Investigation usage");
557
+ expect(usage).toBeVisible();
449
558
  expect(usage).toHaveTextContent("2 telemetry queries");
450
- expect(usage).toHaveTextContent("1,234 tokens");
451
559
  expect(usage).toHaveTextContent(
452
560
  "Read-only — nothing in your systems was changed",
453
561
  );
562
+ expect(screen.getByLabelText("Model and tokens")).toHaveTextContent(
563
+ "1,234 tokens",
564
+ );
454
565
  expect(fixButton()).toBeEnabled();
455
566
  expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
456
567
  expect(screen.getByRole("button", { name: "Rejected" })).toBeEnabled();
@@ -480,6 +591,8 @@ describe("InvestigationPanel report lifecycle", () => {
480
591
  expect(screen.getByText("Preparing investigation report…")).toBeVisible();
481
592
  expect(screen.getByText("Preparing the final report")).toBeVisible();
482
593
  expect(screen.queryByTestId("investigation-markdown")).toBeNull();
594
+ // The steps can already be checked while the report is being written.
595
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
483
596
  expect(onAnalysisAvailable).not.toHaveBeenCalled();
484
597
 
485
598
  /* Status, run id, events and recommendation remain identical. */
@@ -627,6 +740,19 @@ describe("InvestigationPanel report lifecycle", () => {
627
740
  expect(
628
741
  screen.getByText("No investigation report was published."),
629
742
  ).toBeVisible();
743
+ /*
744
+ * No steps were recorded, so the notice does not point at an activity
745
+ * section that is not there, and there is nothing to expand: the run's
746
+ * usage is all that is left to say.
747
+ */
748
+ expect(
749
+ screen.getByText("The run finished without a final analysis."),
750
+ ).toBeVisible();
751
+ expect(screen.queryByText(/Investigation activity/)).toBeNull();
752
+ expect(screen.queryByTestId("investigation-details-toggle")).toBeNull();
753
+ expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
754
+ "0 telemetry queries",
755
+ );
630
756
  expect(fixButton()).toBeDisabled();
631
757
  expect(screen.getByRole("button", { name: "Confirmed" })).toBeDisabled();
632
758
  expect(screen.getByRole("button", { name: "Rejected" })).toBeDisabled();
@@ -720,14 +846,16 @@ describe("InvestigationPanel card states", () => {
720
846
  expect(screen.getByText("Starting investigation…")).toBeVisible();
721
847
  });
722
848
 
723
- test("puts a copy control on the report so it can be pasted elsewhere", async () => {
849
+ test("puts a copy control and a verify-first note on the report", async () => {
724
850
  postMock.mockResolvedValue(completedResponse() as never);
725
851
 
726
852
  renderPanel();
727
853
  await flush();
728
854
 
729
855
  const report: HTMLElement = screen.getByLabelText("Investigation report");
730
- expect(report).toHaveTextContent("AI generated");
856
+ expect(report).toHaveTextContent(
857
+ "AI-generated first pass — verify before acting.",
858
+ );
731
859
  expect(report).toContainElement(
732
860
  screen.getByRole("button", { name: "Copy report" }),
733
861
  );
@@ -762,6 +890,45 @@ describe("InvestigationPanel card states", () => {
762
890
  },
763
891
  );
764
892
 
893
+ /*
894
+ * A failed run has no report and no collapsed details, so what it ran and
895
+ * the read-only guarantee close its own activity frame instead — a reader
896
+ * deciding whether a half-finished run touched anything finds the answer
897
+ * right under the steps it took.
898
+ */
899
+ test("ends a failed run's activity with what it ran and that it changed nothing", async () => {
900
+ postMock.mockResolvedValue(
901
+ successfulResponse(
902
+ investigationPayload({
903
+ status: AIRunStatus.Error,
904
+ errorMessage: "The model provider timed out.",
905
+ events: [activityEvent],
906
+ toolCallCount: 3,
907
+ totalTokens: 900,
908
+ }),
909
+ ) as never,
910
+ );
911
+
912
+ renderPanel();
913
+ await flush();
914
+
915
+ const activity: HTMLElement = screen.getByRole("region", {
916
+ name: "Investigation activity",
917
+ });
918
+ const usage: HTMLElement = within(activity).getByRole("list", {
919
+ name: "Investigation usage",
920
+ });
921
+ expect(activity.lastElementChild).toBe(usage);
922
+ expect(usage).toBeVisible();
923
+ expect(usage).toHaveTextContent("3 telemetry queries");
924
+ expect(usage).toHaveTextContent("900 tokens");
925
+ expect(usage).toHaveTextContent(
926
+ "Read-only — nothing in your systems was changed",
927
+ );
928
+ expect(screen.queryByTestId("investigation-details")).toBeNull();
929
+ expect(screen.getAllByLabelText("Investigation usage")).toHaveLength(1);
930
+ });
931
+
765
932
  /*
766
933
  * Events and rendered steps are not the same thing: RunFailed and the
767
934
  * completion halves of tool/LLM calls only close a step an earlier event
@@ -770,7 +937,7 @@ describe("InvestigationPanel card states", () => {
770
937
  * an empty panel instead of saying what happened.
771
938
  */
772
939
  test("explains an empty trail instead of framing a blank panel", async () => {
773
- hasRenderableActivityMock.mockReturnValue(false);
940
+ countActivityStepsMock.mockReturnValue(0);
774
941
  postMock.mockResolvedValue(
775
942
  successfulResponse(
776
943
  investigationPayload({
@@ -790,8 +957,14 @@ describe("InvestigationPanel card states", () => {
790
957
  ).toBeVisible();
791
958
  });
792
959
 
793
- test("hides the completed activity disclosure when no step would render", async () => {
794
- hasRenderableActivityMock.mockReturnValue(false);
960
+ /*
961
+ * The same event/step mismatch on a completed run: with no evidence and no
962
+ * step to draw, a collapsed section would open onto nothing. The run's
963
+ * usage is all there is, so it stands alone — tokens included, since there
964
+ * is no body to hold them.
965
+ */
966
+ test("offers nothing to expand when a completed run has no evidence and no step would render", async () => {
967
+ countActivityStepsMock.mockReturnValue(0);
795
968
  postMock.mockResolvedValue(completedResponse() as never);
796
969
 
797
970
  renderPanel();
@@ -799,9 +972,17 @@ describe("InvestigationPanel card states", () => {
799
972
 
800
973
  expect(screen.getByLabelText("Investigation report")).toBeInTheDocument();
801
974
  expect(screen.queryByText("Investigation activity")).toBeNull();
975
+ expect(screen.queryByTestId("investigation-details-toggle")).toBeNull();
976
+ expect(screen.queryByTestId("investigation-activity")).toBeNull();
977
+
978
+ const usage: HTMLElement = screen.getByLabelText("Investigation usage");
979
+ expect(usage).toBeVisible();
980
+ expect(usage).toHaveTextContent("2 telemetry queries");
981
+ expect(usage).toHaveTextContent("1,234 tokens");
982
+ expect(usage).not.toHaveTextContent("step");
802
983
  });
803
984
 
804
- test("reports a single query without pluralising it", async () => {
985
+ test("reports a single query and step without pluralising them", async () => {
805
986
  postMock.mockResolvedValue(
806
987
  completedResponse({ toolCallCount: 1, totalTokens: 0 }) as never,
807
988
  );
@@ -811,8 +992,50 @@ describe("InvestigationPanel card states", () => {
811
992
 
812
993
  const usage: HTMLElement = screen.getByLabelText("Investigation usage");
813
994
  expect(usage).toHaveTextContent("1 telemetry query");
995
+ expect(usage).not.toHaveTextContent("queries");
996
+ expect(usage).toHaveTextContent("1 step");
997
+ expect(usage).not.toHaveTextContent("steps");
814
998
  expect(usage).not.toHaveTextContent("tokens");
815
999
  });
1000
+
1001
+ /*
1002
+ * The no-report notice used to send every reader to "the activity below",
1003
+ * even when no step had been recorded and there was nothing below to read.
1004
+ */
1005
+ test("points the no-report notice at the activity only when there is some", async () => {
1006
+ postMock.mockResolvedValue(
1007
+ completedResponse({
1008
+ analysisMarkdown: null,
1009
+ isAnalysisPending: false,
1010
+ }) as never,
1011
+ );
1012
+
1013
+ renderPanel();
1014
+ await flush();
1015
+
1016
+ expect(
1017
+ screen.getByText(
1018
+ "The run finished without a final analysis. Its steps are under Investigation activity below.",
1019
+ ),
1020
+ ).toBeVisible();
1021
+
1022
+ /*
1023
+ * Evidence only exists beside a report, so the section is the activity
1024
+ * alone: named for it, and without tabs once opened.
1025
+ */
1026
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
1027
+ expect(detailsToggle()).not.toHaveTextContent("Evidence");
1028
+ expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
1029
+ "2 telemetry queries",
1030
+ );
1031
+
1032
+ openDetails();
1033
+
1034
+ expect(screen.queryByRole("tablist")).toBeNull();
1035
+ expect(screen.queryByRole("tabpanel")).toBeNull();
1036
+ expect(screen.queryByLabelText("Evidence checked")).toBeNull();
1037
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
1038
+ });
816
1039
  });
817
1040
 
818
1041
  /*
@@ -845,10 +1068,10 @@ describe("InvestigationPanel TL;DR", () => {
845
1068
  // The summary is never routed through the markdown renderer.
846
1069
  expect(markdownTexts().length).toBeGreaterThan(0);
847
1070
  expect(
848
- markdownTexts().every((text: string): boolean => {
849
- return text === ANALYSIS;
1071
+ markdownTexts().some((text: string): boolean => {
1072
+ return text.includes(TLDR);
850
1073
  }),
851
- ).toBe(true);
1074
+ ).toBe(false);
852
1075
 
853
1076
  // It sits above the report it summarizes.
854
1077
  const report: HTMLElement = screen.getByLabelText("Investigation report");
@@ -1021,10 +1244,10 @@ describe("InvestigationPanel TL;DR", () => {
1021
1244
  ).toBeUndefined();
1022
1245
  // The summary never reaches the markdown renderer.
1023
1246
  expect(
1024
- markdownTexts().every((text: string): boolean => {
1025
- return text === ANALYSIS;
1247
+ markdownTexts().some((text: string): boolean => {
1248
+ return text.includes("__pwned");
1026
1249
  }),
1027
- ).toBe(true);
1250
+ ).toBe(false);
1028
1251
  });
1029
1252
 
1030
1253
  test("drops the previous subject's summary the moment the subject changes", async () => {
@@ -1693,3 +1916,1686 @@ describe("InvestigationPanel completed actions", () => {
1693
1916
  expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
1694
1917
  });
1695
1918
  });
1919
+
1920
+ /*
1921
+ * The completed report is laid out for a responder: its Summary in a section
1922
+ * of its own, the report section by section, and every query the AI ran with
1923
+ * the rows behind it one click away. The payload's `evidence` and
1924
+ * `references` drive the interactive parts; older API replicas omit them and
1925
+ * the panel must fall back to the markdown alone.
1926
+ */
1927
+ const PRIOR_INCIDENT_ID: string = "66666666-6666-4666-8666-666666666666";
1928
+ const PRIOR_ALERT_ID: string = "77777777-7777-4777-8777-777777777777";
1929
+ const REPORT_SUMMARY: string =
1930
+ "the connection pool ran dry after the 18:00 deploy.";
1931
+
1932
+ const STRUCTURED_REPORT: string = [
1933
+ "## \u{1F9E0} AI — Automated Root Cause Analysis",
1934
+ "",
1935
+ "**Summary** — the connection pool ran dry after the 18:00 deploy [C1].",
1936
+ "",
1937
+ "**Most likely root cause** — the deploy halved the pool size; this matches prior #6954 [C2].",
1938
+ "",
1939
+ "**Suggested next steps**",
1940
+ "- Roll back the deploy",
1941
+ "",
1942
+ "**Evidence checked**",
1943
+ "- **[C1]** Active incidents (7 total) — 7 row(s)",
1944
+ "- **[C2]** Logs 17:20 – 18:20 (1 shown) — 1 row(s)",
1945
+ "",
1946
+ "---",
1947
+ "*Investigated automatically by OneUptime AI — read-only, 2 queries run across your own telemetry using gpt-5. This is an AI-generated first pass; verify before acting.*",
1948
+ ].join("\n");
1949
+
1950
+ const EVIDENCE_ITEMS: JSONArray = [
1951
+ {
1952
+ citationId: "C1",
1953
+ toolName: "query_incidents",
1954
+ label: "Active incidents (7 total)",
1955
+ rowCount: 7,
1956
+ durationInMs: 812,
1957
+ queryArguments: { state: "active" },
1958
+ target: { type: "Incidents" },
1959
+ executedAt: "2026-08-07T11:58:00.000Z",
1960
+ canLoadRows: true,
1961
+ },
1962
+ {
1963
+ citationId: "C2",
1964
+ toolName: "search_logs",
1965
+ label: "Logs 17:20 – 18:20 (1 shown)",
1966
+ rowCount: 1,
1967
+ queryArguments: { bodySearchText: "pool timeout" },
1968
+ target: { type: "Logs" },
1969
+ executedAt: "2026-08-07T11:59:00.000Z",
1970
+ canLoadRows: true,
1971
+ },
1972
+ ];
1973
+
1974
+ const REFERENCES: JSONArray = [
1975
+ {
1976
+ kind: "incident",
1977
+ number: 6954,
1978
+ id: PRIOR_INCIDENT_ID,
1979
+ displayNumber: "INC-6954",
1980
+ title: "Checkout pool exhausted",
1981
+ stateName: "Resolved",
1982
+ },
1983
+ {
1984
+ kind: "alert",
1985
+ number: 6954,
1986
+ id: PRIOR_ALERT_ID,
1987
+ displayNumber: "#6954",
1988
+ title: "Webhook failures",
1989
+ },
1990
+ ];
1991
+
1992
+ interface EvidencePostRequest extends PostRequest {
1993
+ headers?: JSONObject | undefined;
1994
+ }
1995
+
1996
+ function structuredResponse(
1997
+ overrides: Partial<InvestigationPayloadOptions> = {},
1998
+ ): ApiResponse {
1999
+ return completedResponse({
2000
+ analysisMarkdown: STRUCTURED_REPORT,
2001
+ evidence: EVIDENCE_ITEMS,
2002
+ references: REFERENCES,
2003
+ ...overrides,
2004
+ });
2005
+ }
2006
+
2007
+ function evidenceRowsResponse(citationId: string, text: string): ApiResponse {
2008
+ return successfulResponse({
2009
+ citationId,
2010
+ toolName: "query_incidents",
2011
+ label: "Active incidents (7 total)",
2012
+ rowCount: 7,
2013
+ isTruncated: false,
2014
+ executedAt: COMPLETED_AT,
2015
+ isPinnedToInvestigationTime: false,
2016
+ text,
2017
+ });
2018
+ }
2019
+
2020
+ /*
2021
+ * Investigation polls and evidence re-runs share API.post, so route by URL:
2022
+ * the investigation handler answers the panel's own endpoint and the evidence
2023
+ * handler (default: never resolves) answers /ai-investigation/evidence.
2024
+ */
2025
+ function routePosts(handlers: {
2026
+ investigation: (request: EvidencePostRequest) => unknown;
2027
+ evidence?: ((request: EvidencePostRequest) => unknown) | undefined;
2028
+ }): void {
2029
+ postMock.mockImplementation((request: unknown): unknown => {
2030
+ const typedRequest: EvidencePostRequest = request as EvidencePostRequest;
2031
+
2032
+ if (typedRequest.url.toString().includes("/ai-investigation/evidence")) {
2033
+ return handlers.evidence
2034
+ ? handlers.evidence(typedRequest)
2035
+ : new Promise<never>(() => {});
2036
+ }
2037
+
2038
+ return handlers.investigation(typedRequest);
2039
+ });
2040
+ }
2041
+
2042
+ function evidencePosts(): Array<EvidencePostRequest> {
2043
+ return (postMock.mock.calls as Array<Array<EvidencePostRequest>>)
2044
+ .map((call: Array<EvidencePostRequest>): EvidencePostRequest => {
2045
+ return call[0]!;
2046
+ })
2047
+ .filter((request: EvidencePostRequest): boolean => {
2048
+ return request.url.toString().includes("/ai-investigation/evidence");
2049
+ });
2050
+ }
2051
+
2052
+ function investigationPostCount(): number {
2053
+ return postMock.mock.calls.length - evidencePosts().length;
2054
+ }
2055
+
2056
+ function lastInlineReferences(): MarkdownInlineReferenceRenderers {
2057
+ const calls: Array<Array<MarkdownViewerProps>> = markdownViewerMock.mock
2058
+ .calls as Array<Array<MarkdownViewerProps>>;
2059
+ return calls[calls.length - 1]![0]!.inlineReferences!;
2060
+ }
2061
+
2062
+ function allMarkdownProps(): Array<MarkdownViewerProps> {
2063
+ return (
2064
+ markdownViewerMock.mock.calls as Array<Array<MarkdownViewerProps>>
2065
+ ).map((call: Array<MarkdownViewerProps>): MarkdownViewerProps => {
2066
+ return call[0]!;
2067
+ });
2068
+ }
2069
+
2070
+ describe("InvestigationPanel structured report", () => {
2071
+ const scrollIntoViewMock: MockFunction = getJestMockFunction();
2072
+
2073
+ beforeEach(() => {
2074
+ Object.defineProperty(Element.prototype, "scrollIntoView", {
2075
+ configurable: true,
2076
+ writable: true,
2077
+ value: scrollIntoViewMock,
2078
+ });
2079
+ });
2080
+
2081
+ afterEach(() => {
2082
+ scrollIntoViewMock.mockReset();
2083
+ delete (Element.prototype as unknown as { scrollIntoView?: unknown })
2084
+ .scrollIntoView;
2085
+ });
2086
+
2087
+ test("lifts the report's Summary into its own section above the report", async () => {
2088
+ postMock.mockResolvedValue(structuredResponse() as never);
2089
+
2090
+ renderPanel();
2091
+ await flush();
2092
+
2093
+ const summary: HTMLElement = screen.getByRole("region", {
2094
+ name: "Investigation summary",
2095
+ });
2096
+ expect(summary).toHaveTextContent(
2097
+ "the connection pool ran dry after the 18:00 deploy [C1].",
2098
+ );
2099
+ expect(within(summary).queryByText("TL;DR")).toBeNull();
2100
+
2101
+ const report: HTMLElement = screen.getByRole("region", {
2102
+ name: "Investigation report",
2103
+ });
2104
+ expect(
2105
+ within(report)
2106
+ .getAllByRole("heading", { level: 4 })
2107
+ .map((heading: HTMLElement): string => {
2108
+ return heading.textContent || "";
2109
+ }),
2110
+ ).toEqual(["Most likely root cause", "Suggested next steps"]);
2111
+ expect(report).not.toHaveTextContent("the connection pool ran dry");
2112
+ expect(
2113
+ summary.compareDocumentPosition(report) &
2114
+ Node.DOCUMENT_POSITION_FOLLOWING,
2115
+ ).toBeTruthy();
2116
+
2117
+ for (const props of allMarkdownProps()) {
2118
+ expect(props.safeMode).toBe(true);
2119
+ expect(props.text).not.toContain("Automated Root Cause Analysis");
2120
+ expect(props.text).not.toContain("Evidence checked");
2121
+ expect(props.text).not.toContain("Investigated automatically");
2122
+ }
2123
+ });
2124
+
2125
+ test("renders the evidence the API returns, below the report", async () => {
2126
+ postMock.mockResolvedValue(structuredResponse() as never);
2127
+
2128
+ renderPanel();
2129
+ await flush();
2130
+
2131
+ expect(
2132
+ screen
2133
+ .getByLabelText("Investigation report")
2134
+ .compareDocumentPosition(runDetails()) &
2135
+ Node.DOCUMENT_POSITION_FOLLOWING,
2136
+ ).toBeTruthy();
2137
+
2138
+ openDetails();
2139
+
2140
+ // The tab carries the query count the old list header used to show.
2141
+ expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
2142
+ "Evidence checked2",
2143
+ );
2144
+ const evidence: HTMLElement = evidenceList();
2145
+ expect(runDetails()).toContainElement(evidence);
2146
+ expect(within(evidence).getAllByRole("listitem")).toHaveLength(2);
2147
+ expect(
2148
+ within(evidence).getByRole("button", { name: /Active incidents/ }),
2149
+ ).toHaveAttribute("aria-expanded", "false");
2150
+ // Rendering evidence never re-runs anything by itself.
2151
+ expect(evidencePosts()).toHaveLength(0);
2152
+ expect(jest.getTimerCount()).toBe(1);
2153
+ });
2154
+
2155
+ test("expanding a query POSTs its citation once and shows the rows", async () => {
2156
+ routePosts({
2157
+ investigation: (): unknown => {
2158
+ return Promise.resolve(structuredResponse());
2159
+ },
2160
+ evidence: (): unknown => {
2161
+ return Promise.resolve(
2162
+ evidenceRowsResponse("C1", "id | title\n1 | Checkout down"),
2163
+ );
2164
+ },
2165
+ });
2166
+
2167
+ renderPanel();
2168
+ await flush();
2169
+ openDetails();
2170
+
2171
+ const toggle: HTMLElement = screen.getByRole("button", {
2172
+ name: /Active incidents \(7 total\)/,
2173
+ });
2174
+ fireEvent.click(toggle);
2175
+ await flush();
2176
+
2177
+ expect(evidencePosts()).toHaveLength(1);
2178
+ expect(evidencePosts()[0]!.data).toEqual({
2179
+ subjectType: "incident",
2180
+ subjectId: INCIDENT_ID.toString(),
2181
+ investigationRunId: RUN_ID,
2182
+ citationId: "C1",
2183
+ });
2184
+ expect(screen.getByText(/Checkout down/)).toBeVisible();
2185
+
2186
+ // Collapse and re-open: served from the cache.
2187
+ fireEvent.click(toggle);
2188
+ fireEvent.click(toggle);
2189
+ await flush();
2190
+
2191
+ expect(evidencePosts()).toHaveLength(1);
2192
+ expect(investigationPostCount()).toBe(1);
2193
+ });
2194
+
2195
+ test("falls back to the report's own Evidence checked list for an older API", async () => {
2196
+ postMock.mockResolvedValue(
2197
+ completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
2198
+ );
2199
+
2200
+ renderPanel();
2201
+ await flush();
2202
+ openDetails();
2203
+
2204
+ const evidence: HTMLElement = evidenceList();
2205
+ expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
2206
+ "Evidence checked2",
2207
+ );
2208
+ expect(evidence).toHaveTextContent("Active incidents (7 total)");
2209
+ expect(evidence).toHaveTextContent("Logs 17:20 – 18:20 (1 shown)");
2210
+ expect(within(evidence).queryAllByRole("button")).toHaveLength(0);
2211
+ // No references from an older API, so numbers stay plain text.
2212
+ expect(
2213
+ lastInlineReferences().renderEventReference!({
2214
+ kind: null,
2215
+ number: 6954,
2216
+ text: "#6954",
2217
+ }),
2218
+ ).toBeNull();
2219
+ });
2220
+
2221
+ test("picks up evidence that arrives on a later poll", async () => {
2222
+ postMock
2223
+ .mockResolvedValueOnce(
2224
+ completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
2225
+ )
2226
+ .mockResolvedValue(structuredResponse() as never);
2227
+
2228
+ renderPanel();
2229
+ await flush();
2230
+ openDetails();
2231
+ expect(within(evidenceList()).getAllByRole("listitem")).toHaveLength(2);
2232
+ expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
2233
+
2234
+ await tick(SETTLED_POLL_INTERVAL_MS);
2235
+
2236
+ // Still open on the same list, now with a toggle per query.
2237
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2238
+ expect(within(evidenceList()).getAllByRole("button")).toHaveLength(2);
2239
+ });
2240
+
2241
+ test("never shows evidence without the report it belongs to", async () => {
2242
+ postMock.mockResolvedValue(
2243
+ completedResponse({
2244
+ analysisMarkdown: null,
2245
+ isAnalysisPending: true,
2246
+ evidence: EVIDENCE_ITEMS,
2247
+ references: REFERENCES,
2248
+ }) as never,
2249
+ );
2250
+
2251
+ renderPanel();
2252
+ await flush();
2253
+
2254
+ expect(screen.getByText("Preparing the final report")).toBeVisible();
2255
+ expect(screen.queryByLabelText("Evidence checked")).toBeNull();
2256
+
2257
+ // The section still offers the run's steps, and only those.
2258
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
2259
+ openDetails();
2260
+ expect(screen.queryByRole("tablist")).toBeNull();
2261
+ expect(screen.queryByLabelText("Evidence checked")).toBeNull();
2262
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
2263
+ });
2264
+
2265
+ test("drops evidence when the report disappears on a later poll", async () => {
2266
+ postMock
2267
+ .mockResolvedValueOnce(structuredResponse() as never)
2268
+ .mockResolvedValue(
2269
+ structuredResponse({ analysisMarkdown: null }) as never,
2270
+ );
2271
+
2272
+ renderPanel();
2273
+ await flush();
2274
+ expect(screen.getByLabelText("Evidence checked")).toBeInTheDocument();
2275
+ expect(detailsToggle()).toHaveTextContent("Evidence and activity");
2276
+
2277
+ await tick(SETTLED_POLL_INTERVAL_MS);
2278
+
2279
+ expect(screen.queryByLabelText("Evidence checked")).toBeNull();
2280
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
2281
+ expect(
2282
+ screen.getByText("No investigation report was published."),
2283
+ ).toBeVisible();
2284
+ });
2285
+
2286
+ test("ignores malformed evidence and references from the API", async () => {
2287
+ postMock.mockResolvedValue(
2288
+ completedResponse({
2289
+ analysisMarkdown: STRUCTURED_REPORT,
2290
+ evidence: [
2291
+ { citationId: "not-a-citation", toolName: "search_logs" },
2292
+ { citationId: "C1" },
2293
+ ] as unknown as JSONArray,
2294
+ references: [
2295
+ { kind: "incident", number: 6954, id: "javascript:alert(1)" },
2296
+ ] as unknown as JSONArray,
2297
+ }) as never,
2298
+ );
2299
+
2300
+ renderPanel();
2301
+ await flush();
2302
+ openDetails();
2303
+
2304
+ // Nothing valid survived, so the legacy list and plain numbers are used.
2305
+ expect(within(evidenceList()).getAllByRole("listitem")).toHaveLength(2);
2306
+ expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
2307
+ expect(
2308
+ lastInlineReferences().renderEventReference!({
2309
+ kind: "incident",
2310
+ number: 6954,
2311
+ text: "#6954",
2312
+ }),
2313
+ ).toBeNull();
2314
+ });
2315
+
2316
+ /*
2317
+ * The report's chips are rendered by the markdown viewer, which is mocked
2318
+ * here, so render the panel's own chip renderer output and click it the
2319
+ * way a reader would.
2320
+ */
2321
+ function clickCitation(citationId: string, name: string): void {
2322
+ const chip: React.ReactElement | null =
2323
+ lastInlineReferences().renderCitation!(citationId);
2324
+ expect(chip).not.toBeNull();
2325
+ render(chip!);
2326
+
2327
+ const chipButton: HTMLElement = screen.getByRole("button", { name });
2328
+ fireEvent.click(chipButton);
2329
+ }
2330
+
2331
+ /*
2332
+ * The evidence sits in a section that starts collapsed, so a chip that only
2333
+ * highlighted its row would highlight something nobody can see. The chip
2334
+ * has to open the section on the Evidence tab first.
2335
+ */
2336
+ test("a citation chip opens the collapsed details and expands, scrolls to and highlights its row", async () => {
2337
+ routePosts({
2338
+ investigation: (): unknown => {
2339
+ return Promise.resolve(structuredResponse());
2340
+ },
2341
+ });
2342
+
2343
+ renderPanel();
2344
+ await flush();
2345
+ expect(jest.getTimerCount()).toBe(1);
2346
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
2347
+ expect(detailsBody()).not.toBeVisible();
2348
+
2349
+ const chip: React.ReactElement | null =
2350
+ lastInlineReferences().renderCitation!("C2");
2351
+ expect(chip).not.toBeNull();
2352
+ render(chip!);
2353
+
2354
+ const chipButton: HTMLElement = screen.getByRole("button", {
2355
+ name: "Citation C2: Logs 17:20 – 18:20 (1 shown)",
2356
+ });
2357
+ expect(chipButton).toHaveAttribute("title", "Logs 17:20 – 18:20 (1 shown)");
2358
+
2359
+ fireEvent.click(chipButton);
2360
+ await flush();
2361
+
2362
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2363
+ expect(detailsBody()).toBeVisible();
2364
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
2365
+ "aria-selected",
2366
+ "true",
2367
+ );
2368
+
2369
+ const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
2370
+ name: /Logs 17:20/,
2371
+ });
2372
+ expect(toggle).toBeVisible();
2373
+ expect(toggle).toHaveAttribute("aria-expanded", "true");
2374
+ expect(toggle).toHaveFocus();
2375
+ expect(toggle.closest("li")).toHaveAttribute("data-highlighted", "true");
2376
+ expect(scrollIntoViewMock).toHaveBeenCalledWith({
2377
+ block: "nearest",
2378
+ behavior: "smooth",
2379
+ });
2380
+ expect(evidencePosts()).toHaveLength(1);
2381
+ expect(evidencePosts()[0]!.data["citationId"]).toBe("C2");
2382
+ // The settled poll plus the single highlight timer.
2383
+ expect(jest.getTimerCount()).toBe(2);
2384
+
2385
+ await tick(2000);
2386
+
2387
+ expect(toggle.closest("li")).not.toHaveAttribute("data-highlighted");
2388
+ expect(jest.getTimerCount()).toBe(1);
2389
+ // The highlight fades; the section the reader was taken to stays open.
2390
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2391
+ });
2392
+
2393
+ test("a citation chip switches an open section from Activity to Evidence", async () => {
2394
+ routePosts({
2395
+ investigation: (): unknown => {
2396
+ return Promise.resolve(structuredResponse());
2397
+ },
2398
+ });
2399
+
2400
+ renderPanel();
2401
+ await flush();
2402
+ openDetails();
2403
+ fireEvent.click(detailsTab(/^Activity/));
2404
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
2405
+ expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
2406
+
2407
+ clickCitation("C1", "Citation C1: Active incidents (7 total)");
2408
+ await flush();
2409
+
2410
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2411
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
2412
+ "aria-selected",
2413
+ "true",
2414
+ );
2415
+ expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "false");
2416
+ expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
2417
+
2418
+ const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
2419
+ name: /Active incidents/,
2420
+ });
2421
+ expect(toggle).toBeVisible();
2422
+ expect(toggle).toHaveAttribute("aria-expanded", "true");
2423
+ expect(toggle).toHaveFocus();
2424
+ expect(toggle.closest("li")).toHaveAttribute("data-highlighted", "true");
2425
+ expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
2426
+ });
2427
+
2428
+ /*
2429
+ * An older API sends no structured evidence, so the report's own list is
2430
+ * shown and its rows have no toggle. The row itself takes focus, or a
2431
+ * keyboard or screen-reader user would be left on the chip.
2432
+ */
2433
+ test("a citation chip on an older report reveals and focuses its plain row", async () => {
2434
+ postMock.mockResolvedValue(
2435
+ completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
2436
+ );
2437
+
2438
+ renderPanel();
2439
+ await flush();
2440
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
2441
+
2442
+ clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
2443
+ await flush();
2444
+
2445
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2446
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
2447
+ "aria-selected",
2448
+ "true",
2449
+ );
2450
+
2451
+ const row: HTMLElement = within(evidenceList())
2452
+ .getAllByRole("listitem")
2453
+ .find((item: HTMLElement): boolean => {
2454
+ return item.textContent?.includes("Logs 17:20") === true;
2455
+ })!;
2456
+ expect(row).toBeVisible();
2457
+ expect(row).toHaveFocus();
2458
+ expect(row).toHaveAttribute("data-highlighted", "true");
2459
+ expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
2460
+ // A plain row has nothing to re-run.
2461
+ expect(evidencePosts()).toHaveLength(0);
2462
+ });
2463
+
2464
+ /*
2465
+ * A chip's request lives in the panel, so it outlives the evidence list
2466
+ * when the report briefly disappears between polls. When the list comes
2467
+ * back it must not replay that old request — scrolling the page and
2468
+ * stealing focus with no click behind it.
2469
+ */
2470
+ test("does not replay a chip when the evidence comes back on a later poll", async () => {
2471
+ let investigationCalls: number = 0;
2472
+ routePosts({
2473
+ investigation: (): unknown => {
2474
+ investigationCalls += 1;
2475
+ return Promise.resolve(
2476
+ investigationCalls === 2
2477
+ ? structuredResponse({ analysisMarkdown: null })
2478
+ : structuredResponse(),
2479
+ );
2480
+ },
2481
+ });
2482
+
2483
+ renderPanel();
2484
+ await flush();
2485
+ clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
2486
+ await flush();
2487
+ expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
2488
+ await tick(2000);
2489
+
2490
+ await tick(SETTLED_POLL_INTERVAL_MS);
2491
+ expect(screen.queryByLabelText("Evidence checked")).toBeNull();
2492
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
2493
+
2494
+ await tick(SETTLED_POLL_INTERVAL_MS);
2495
+ expect(investigationPostCount()).toBe(3);
2496
+
2497
+ const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
2498
+ name: /Logs 17:20/,
2499
+ });
2500
+ expect(toggle).toBeVisible();
2501
+ expect(toggle).toHaveAttribute("aria-expanded", "false");
2502
+ expect(toggle).not.toHaveFocus();
2503
+ expect(document.querySelector('[data-highlighted="true"]')).toBeNull();
2504
+ expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
2505
+ expect(evidencePosts()).toHaveLength(1);
2506
+ });
2507
+
2508
+ test("a new run on the same subject starts collapsed, even after a chip opened the last one", async () => {
2509
+ let investigationCalls: number = 0;
2510
+ routePosts({
2511
+ investigation: (): unknown => {
2512
+ investigationCalls += 1;
2513
+ return Promise.resolve(
2514
+ investigationCalls === 1
2515
+ ? structuredResponse()
2516
+ : structuredResponse({ runId: NEXT_RUN_ID }),
2517
+ );
2518
+ },
2519
+ });
2520
+
2521
+ renderPanel();
2522
+ await flush();
2523
+ clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
2524
+ await flush();
2525
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
2526
+
2527
+ await tick(SETTLED_POLL_INTERVAL_MS);
2528
+
2529
+ expect(investigationPostCount()).toBe(2);
2530
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
2531
+ expect(detailsBody()).not.toBeVisible();
2532
+
2533
+ openDetails();
2534
+
2535
+ expect(
2536
+ within(evidenceList()).getByRole("button", { name: /Logs 17:20/ }),
2537
+ ).toHaveAttribute("aria-expanded", "false");
2538
+ expect(document.querySelector('[data-highlighted="true"]')).toBeNull();
2539
+ expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
2540
+ });
2541
+
2542
+ test("leaves a citation that is not in the evidence as plain text", async () => {
2543
+ postMock.mockResolvedValue(structuredResponse() as never);
2544
+
2545
+ renderPanel();
2546
+ await flush();
2547
+
2548
+ expect(lastInlineReferences().renderCitation!("C9")).toBeNull();
2549
+ expect(lastInlineReferences().renderCitation!("C1")).not.toBeNull();
2550
+ });
2551
+
2552
+ test("links a referenced incident number to that incident", async () => {
2553
+ postMock.mockResolvedValue(structuredResponse() as never);
2554
+
2555
+ renderPanel();
2556
+ await flush();
2557
+
2558
+ const link: React.ReactElement | null = lastInlineReferences()
2559
+ .renderEventReference!({
2560
+ kind: null,
2561
+ number: 6954,
2562
+ text: "#6954",
2563
+ });
2564
+ expect(link).not.toBeNull();
2565
+ render(link!);
2566
+
2567
+ const anchor: HTMLElement = screen.getByRole("link", {
2568
+ name: "INC-6954 · Checkout pool exhausted · Resolved",
2569
+ });
2570
+ expect(anchor).toHaveTextContent("#6954");
2571
+ expect(anchor.getAttribute("href")).toMatch(
2572
+ new RegExp(`/incidents/${PRIOR_INCIDENT_ID}$`),
2573
+ );
2574
+ expect(
2575
+ lastInlineReferences().renderEventReference!({
2576
+ kind: "incident",
2577
+ number: 1,
2578
+ text: "#1",
2579
+ }),
2580
+ ).toBeNull();
2581
+ });
2582
+
2583
+ test("resolves an unqualified number as an alert on an alert investigation", async () => {
2584
+ postMock.mockResolvedValue(structuredResponse() as never);
2585
+
2586
+ renderPanel({ subjectType: "alert", subjectId: ALERT_ID });
2587
+ await flush();
2588
+
2589
+ const link: React.ReactElement | null = lastInlineReferences()
2590
+ .renderEventReference!({
2591
+ kind: null,
2592
+ number: 6954,
2593
+ text: "#6954",
2594
+ });
2595
+ render(link!);
2596
+
2597
+ expect(
2598
+ screen
2599
+ .getByRole("link", { name: "#6954 · Webhook failures" })
2600
+ .getAttribute("href"),
2601
+ ).toMatch(new RegExp(`/alerts/${PRIOR_ALERT_ID}$`));
2602
+ });
2603
+
2604
+ test("ignores evidence rows that resolve after navigating to another subject", async () => {
2605
+ const staleRows: Deferred<ApiResponse> = createDeferred<ApiResponse>();
2606
+ let evidenceCalls: number = 0;
2607
+ routePosts({
2608
+ investigation: (request: EvidencePostRequest): unknown => {
2609
+ return Promise.resolve(
2610
+ request.data["alertId"]
2611
+ ? structuredResponse({ runId: NEXT_RUN_ID })
2612
+ : structuredResponse(),
2613
+ );
2614
+ },
2615
+ evidence: (): unknown => {
2616
+ evidenceCalls += 1;
2617
+ return evidenceCalls === 1
2618
+ ? staleRows.promise
2619
+ : Promise.resolve(
2620
+ evidenceRowsResponse("C1", "id | title\n9 | Alert subject rows"),
2621
+ );
2622
+ },
2623
+ });
2624
+
2625
+ const view: ReturnType<typeof render> = renderPanel();
2626
+ await flush();
2627
+ openDetails();
2628
+ fireEvent.click(
2629
+ screen.getByRole("button", { name: /Active incidents \(7 total\)/ }),
2630
+ );
2631
+ await flush();
2632
+ expect(evidencePosts()).toHaveLength(1);
2633
+
2634
+ view.rerender(
2635
+ <InvestigationPanel subjectType="alert" subjectId={ALERT_ID} />,
2636
+ );
2637
+ await flush();
2638
+ await resolveDeferred(
2639
+ staleRows,
2640
+ evidenceRowsResponse("C1", "id | title\n1 | Previous subject rows"),
2641
+ );
2642
+
2643
+ expect(screen.queryByText(/Previous subject rows/)).toBeNull();
2644
+ // The new subject's details start collapsed like any other.
2645
+ openDetails();
2646
+ const toggle: HTMLElement = screen.getByRole("button", {
2647
+ name: /Active incidents \(7 total\)/,
2648
+ });
2649
+ expect(toggle).toHaveAttribute("aria-expanded", "false");
2650
+
2651
+ fireEvent.click(toggle);
2652
+ await flush();
2653
+
2654
+ expect(screen.getByText(/Alert subject rows/)).toBeVisible();
2655
+ expect(screen.queryByText(/Previous subject rows/)).toBeNull();
2656
+ expect(evidencePosts()[1]!.data).toEqual({
2657
+ subjectType: "alert",
2658
+ subjectId: ALERT_ID.toString(),
2659
+ investigationRunId: NEXT_RUN_ID,
2660
+ citationId: "C1",
2661
+ });
2662
+ });
2663
+
2664
+ test("renders a hostile report only through the safe viewer", async () => {
2665
+ const hostile: string = [
2666
+ '**Summary** — <img src=x onerror="window.__panelPwned = true"> [click](https://evil.example)',
2667
+ "",
2668
+ "**Most likely root cause** — ![pixel](https://evil.example/p.png) [C1]",
2669
+ "",
2670
+ "[C1]: https://evil.example/exfil",
2671
+ ].join("\n");
2672
+ postMock.mockResolvedValue(
2673
+ structuredResponse({ analysisMarkdown: hostile }) as never,
2674
+ );
2675
+
2676
+ const { container } = renderPanel();
2677
+ await flush();
2678
+
2679
+ expect(allMarkdownProps().length).toBeGreaterThan(0);
2680
+ for (const props of allMarkdownProps()) {
2681
+ expect(props.safeMode).toBe(true);
2682
+ }
2683
+ expect(container.querySelector("img")).toBeNull();
2684
+ expect(container.querySelector("a")).toBeNull();
2685
+ expect(
2686
+ (window as unknown as { __panelPwned?: boolean }).__panelPwned,
2687
+ ).toBeUndefined();
2688
+ });
2689
+
2690
+ /*
2691
+ * Collapsed, the header answers "what did it do, and did it touch
2692
+ * anything?". What the run cost and which model wrote the report are for
2693
+ * the reader who opens the details, and the verify-first note belongs on
2694
+ * the report it qualifies.
2695
+ */
2696
+ test("names the model and its tokens inside the details, not in the collapsed header", async () => {
2697
+ postMock.mockResolvedValue(structuredResponse() as never);
2698
+
2699
+ renderPanel();
2700
+ await flush();
2701
+
2702
+ const usage: HTMLElement = screen.getByLabelText("Investigation usage");
2703
+ expect(usage).toBeVisible();
2704
+ expect(usage).toHaveTextContent("2 telemetry queries");
2705
+ expect(usage).not.toHaveTextContent("tokens");
2706
+ expect(usage).not.toHaveTextContent("gpt-5");
2707
+
2708
+ const cost: HTMLElement = screen.getByLabelText("Model and tokens");
2709
+ expect(detailsBody()).toContainElement(cost);
2710
+ expect(cost).not.toBeVisible();
2711
+ expect(cost).toHaveTextContent("1,234 tokens");
2712
+ expect(cost).toHaveTextContent("Model gpt-5");
2713
+ // Counts and the guarantee are already in the header; no repeats.
2714
+ expect(cost).not.toHaveTextContent("telemetry");
2715
+ expect(cost).not.toHaveTextContent("Read-only");
2716
+
2717
+ openDetails();
2718
+
2719
+ expect(screen.getByRole("list", { name: "Model and tokens" })).toBe(cost);
2720
+ expect(cost).toBeVisible();
2721
+ expect(screen.getByLabelText("Investigation report")).toHaveTextContent(
2722
+ "AI-generated first pass — verify before acting.",
2723
+ );
2724
+ });
2725
+
2726
+ test("does not ask to verify a report that does not exist", async () => {
2727
+ postMock.mockResolvedValue(
2728
+ successfulResponse(
2729
+ investigationPayload({
2730
+ status: AIRunStatus.Error,
2731
+ errorMessage: "The provider timed out.",
2732
+ toolCallCount: 3,
2733
+ }),
2734
+ ) as never,
2735
+ );
2736
+
2737
+ renderPanel();
2738
+ await flush();
2739
+
2740
+ const usage: HTMLElement = screen.getByLabelText("Investigation usage");
2741
+ expect(usage).toHaveTextContent("3 telemetry queries");
2742
+ expect(usage).not.toHaveTextContent("Model");
2743
+ expect(screen.queryByText(/verify before acting/)).toBeNull();
2744
+ expect(screen.queryByLabelText("Model and tokens")).toBeNull();
2745
+ });
2746
+
2747
+ test("titles the act and rate blocks with headings instead of icon-in-paragraph", async () => {
2748
+ postMock.mockResolvedValue(completedResponse() as never);
2749
+
2750
+ const { container } = renderPanel();
2751
+ await flush();
2752
+
2753
+ expect(
2754
+ screen.getByRole("heading", { name: "Act on this investigation" }),
2755
+ ).toBeVisible();
2756
+ expect(
2757
+ screen.getByRole("heading", { name: "Rate this investigation" }),
2758
+ ).toBeVisible();
2759
+ expect(container.querySelectorAll("p div")).toHaveLength(0);
2760
+ });
2761
+ });
2762
+
2763
+ /*
2764
+ * "Evidence checked", "Investigation activity" and the usage strip used to be
2765
+ * three stacked boxes under the report. They are now one section that starts
2766
+ * collapsed: the report is the answer, this is its working. Collapsed, it
2767
+ * still has to say what the run did and that it changed nothing, because a
2768
+ * responder asks that before trusting the report at all.
2769
+ */
2770
+ describe("InvestigationPanel run details", () => {
2771
+ function tabNames(): Array<string> {
2772
+ return within(
2773
+ screen.getByRole("tablist", { name: "Investigation details" }),
2774
+ )
2775
+ .getAllByRole("tab")
2776
+ .map((tab: HTMLElement): string => {
2777
+ return tab.textContent || "";
2778
+ });
2779
+ }
2780
+
2781
+ test("starts collapsed and still says what the run did in its header", async () => {
2782
+ postMock.mockResolvedValue(structuredResponse() as never);
2783
+
2784
+ renderPanel();
2785
+ await flush();
2786
+
2787
+ const section: HTMLElement = screen.getByRole("region", {
2788
+ name: "Evidence and activity",
2789
+ });
2790
+ expect(section).toBe(runDetails());
2791
+
2792
+ /*
2793
+ * The toggle is named by the title alone: the usage line beside it is
2794
+ * not part of the button, so a screen reader hears a short name.
2795
+ */
2796
+ const toggle: HTMLElement = within(section).getByRole("button", {
2797
+ name: "Evidence and activity",
2798
+ });
2799
+ expect(toggle).toBe(detailsToggle());
2800
+ expect(
2801
+ within(section).getByRole("heading", {
2802
+ level: 3,
2803
+ name: "Evidence and activity",
2804
+ }),
2805
+ ).toContainElement(toggle);
2806
+ expect(toggle).toHaveAttribute("aria-expanded", "false");
2807
+ expect(detailsBody()).not.toBeVisible();
2808
+ expect(section).toContainElement(detailsBody());
2809
+ expect(screen.queryByRole("tablist")).toBeNull();
2810
+ expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
2811
+ expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
2812
+
2813
+ const usage: HTMLElement = within(section).getByRole("list", {
2814
+ name: "Investigation usage",
2815
+ });
2816
+ expect(usage).toBeVisible();
2817
+ expect(
2818
+ within(usage)
2819
+ .getAllByRole("listitem")
2820
+ .map((item: HTMLElement): string => {
2821
+ return item.textContent || "";
2822
+ }),
2823
+ ).toEqual([
2824
+ "2 telemetry queries",
2825
+ "1 step",
2826
+ "Read-only — nothing in your systems was changed",
2827
+ ]);
2828
+ });
2829
+
2830
+ /*
2831
+ * The run's tool-call count also includes calls that failed and never
2832
+ * became evidence. Inside a section whose Evidence tab lists the queries,
2833
+ * the header has to count the same queries, or the two numbers a reader
2834
+ * sees side by side disagree. Without evidence the run's own count is all
2835
+ * there is.
2836
+ */
2837
+ test("counts the queries the Evidence tab lists, not the run's raw call count", async () => {
2838
+ postMock
2839
+ .mockResolvedValueOnce(structuredResponse({ toolCallCount: 3 }) as never)
2840
+ .mockResolvedValue(
2841
+ structuredResponse({ toolCallCount: 3, evidence: [] }) as never,
2842
+ );
2843
+
2844
+ renderPanel();
2845
+ await flush();
2846
+
2847
+ expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
2848
+ "2 telemetry queries",
2849
+ );
2850
+ openDetails();
2851
+ expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
2852
+ "Evidence checked2",
2853
+ );
2854
+
2855
+ /*
2856
+ * An older API: the report's own list still names the queries, so the
2857
+ * header follows it rather than the raw call count.
2858
+ */
2859
+ await tick(SETTLED_POLL_INTERVAL_MS);
2860
+
2861
+ expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
2862
+ expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
2863
+ "2 telemetry queries",
2864
+ );
2865
+ });
2866
+
2867
+ test("falls back to the run's call count when there is no evidence at all", async () => {
2868
+ postMock.mockResolvedValue(
2869
+ completedResponse({ toolCallCount: 3 }) as never,
2870
+ );
2871
+
2872
+ renderPanel();
2873
+ await flush();
2874
+
2875
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
2876
+ expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
2877
+ "3 telemetry queries",
2878
+ );
2879
+ });
2880
+
2881
+ test("opening reveals the tabs and the evidence list, and closing hides them again", async () => {
2882
+ postMock.mockResolvedValue(structuredResponse() as never);
2883
+
2884
+ renderPanel();
2885
+ await flush();
2886
+ openDetails();
2887
+
2888
+ expect(detailsBody()).toBeVisible();
2889
+ expect(tabNames()).toEqual(["Evidence checked2", "Activity1"]);
2890
+
2891
+ const evidenceTab: HTMLElement = detailsTab(/^Evidence checked/);
2892
+ expect(evidenceTab).toHaveAttribute("aria-selected", "true");
2893
+ expect(evidenceTab).toHaveAttribute("tabindex", "0");
2894
+ expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "false");
2895
+ expect(detailsTab(/^Activity/)).toHaveAttribute("tabindex", "-1");
2896
+
2897
+ // Only the selected panel is reachable, and it is named by its tab.
2898
+ const panel: HTMLElement = screen.getByRole("tabpanel");
2899
+ expect(panel).toBe(
2900
+ screen.getByRole("tabpanel", { name: /^Evidence checked/ }),
2901
+ );
2902
+ expect(evidenceTab).toHaveAttribute("aria-controls", panel.id);
2903
+ expect(panel).toHaveAttribute("tabindex", "0");
2904
+ expect(panel).toContainElement(evidenceList());
2905
+ expect(
2906
+ within(evidenceList()).getByRole("button", { name: /Active incidents/ }),
2907
+ ).toBeVisible();
2908
+ expect(
2909
+ within(evidenceList()).getByRole("button", { name: /Logs 17:20/ }),
2910
+ ).toBeVisible();
2911
+ expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
2912
+
2913
+ fireEvent.click(detailsToggle());
2914
+
2915
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
2916
+ expect(detailsBody()).not.toBeVisible();
2917
+ expect(screen.queryByRole("tablist")).toBeNull();
2918
+ expect(screen.queryByRole("tabpanel")).toBeNull();
2919
+ expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
2920
+ // The header's summary does not depend on the body being open.
2921
+ expect(screen.getByLabelText("Investigation usage")).toBeVisible();
2922
+ });
2923
+
2924
+ test("switches between the evidence and activity tabs", async () => {
2925
+ postMock.mockResolvedValue(structuredResponse() as never);
2926
+
2927
+ renderPanel();
2928
+ await flush();
2929
+ openDetails();
2930
+
2931
+ fireEvent.click(detailsTab(/^Activity/));
2932
+
2933
+ expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "true");
2934
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
2935
+ "aria-selected",
2936
+ "false",
2937
+ );
2938
+ const activityPanel: HTMLElement = screen.getByRole("tabpanel", {
2939
+ name: /^Activity/,
2940
+ });
2941
+ expect(activityPanel).toContainElement(
2942
+ screen.getByTestId("investigation-activity"),
2943
+ );
2944
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
2945
+ expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
2946
+
2947
+ // The footer belongs to the body, not to one tab.
2948
+ expect(
2949
+ screen.getByRole("list", { name: "Model and tokens" }),
2950
+ ).toBeVisible();
2951
+
2952
+ fireEvent.click(detailsTab(/^Evidence checked/));
2953
+
2954
+ expect(evidenceList()).toBeVisible();
2955
+ expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
2956
+ });
2957
+
2958
+ /*
2959
+ * The old disclosure advertised the raw event count and showed only the
2960
+ * last ten steps. Several event types only close a step, so the count the
2961
+ * reader sees has to be the steps the feed draws — and a finished run is
2962
+ * short enough to show its whole trail.
2963
+ */
2964
+ test("counts the steps the feed draws and shows the whole finished trail", async () => {
2965
+ const events: JSONArray = [];
2966
+
2967
+ for (let index: number = 0; index < 24; index++) {
2968
+ events.push({
2969
+ _id: `55555555-5555-4555-8555-${String(index).padStart(12, "0")}`,
2970
+ sequence: index + 1,
2971
+ eventType:
2972
+ index % 2 === 0
2973
+ ? AIRunEventType.ToolCallStarted
2974
+ : AIRunEventType.ToolCallCompleted,
2975
+ toolName: "search_logs",
2976
+ createdAt: new Date("2026-08-07T10:00:00.000Z"),
2977
+ });
2978
+ }
2979
+
2980
+ countActivityStepsMock.mockReturnValue(12);
2981
+ postMock.mockResolvedValue(structuredResponse({ events }) as never);
2982
+
2983
+ renderPanel();
2984
+ await flush();
2985
+
2986
+ const usage: HTMLElement = screen.getByLabelText("Investigation usage");
2987
+ expect(usage).toHaveTextContent("12 steps");
2988
+ expect(usage).not.toHaveTextContent("24");
2989
+
2990
+ openDetails();
2991
+
2992
+ expect(tabNames()).toEqual(["Evidence checked2", "Activity12"]);
2993
+ expect(lastActivityProps().events).toHaveLength(24);
2994
+ expect(lastActivityProps()).toEqual(
2995
+ expect.objectContaining({
2996
+ hideChrome: true,
2997
+ showLiveIndicator: false,
2998
+ maxVisibleSteps: 12,
2999
+ }),
3000
+ );
3001
+ });
3002
+
3003
+ /*
3004
+ * Evidence can land on a later poll than the report. A reader who opened
3005
+ * the section onto the activity is reading it; the arriving evidence adds
3006
+ * a tab beside it rather than yanking the view to the new first tab.
3007
+ */
3008
+ test("keeps a reader on the activity when evidence arrives after they opened it", async () => {
3009
+ postMock
3010
+ .mockResolvedValueOnce(completedResponse() as never)
3011
+ .mockResolvedValue(structuredResponse() as never);
3012
+
3013
+ renderPanel();
3014
+ await flush();
3015
+ openDetails();
3016
+
3017
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
3018
+ expect(screen.queryByRole("tablist")).toBeNull();
3019
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
3020
+
3021
+ await tick(SETTLED_POLL_INTERVAL_MS);
3022
+
3023
+ expect(detailsToggle()).toHaveTextContent("Evidence and activity");
3024
+ expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
3025
+ expect(tabNames()).toEqual(["Evidence checked2", "Activity1"]);
3026
+ expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "true");
3027
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
3028
+ "aria-selected",
3029
+ "false",
3030
+ );
3031
+ expect(screen.getByTestId("investigation-activity")).toBeVisible();
3032
+ expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
3033
+ });
3034
+
3035
+ /*
3036
+ * The counterpart: nobody has looked yet, so there is nothing to keep, and
3037
+ * the section opens on the evidence like any report that has some.
3038
+ */
3039
+ test("opens on the evidence when it arrived before the reader looked", async () => {
3040
+ postMock
3041
+ .mockResolvedValueOnce(completedResponse() as never)
3042
+ .mockResolvedValue(structuredResponse() as never);
3043
+
3044
+ renderPanel();
3045
+ await flush();
3046
+ await tick(SETTLED_POLL_INTERVAL_MS);
3047
+ openDetails();
3048
+
3049
+ expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
3050
+ "aria-selected",
3051
+ "true",
3052
+ );
3053
+ expect(evidenceList()).toBeVisible();
3054
+ });
3055
+ });
3056
+
3057
+ describe("InvestigationPanel report summary callback", () => {
3058
+ function nonNullCalls(callback: MockFunction): Array<unknown> {
3059
+ return callback.mock.calls
3060
+ .map((call: Array<unknown>): unknown => {
3061
+ return call[0];
3062
+ })
3063
+ .filter((value: unknown): boolean => {
3064
+ return value !== null;
3065
+ });
3066
+ }
3067
+
3068
+ test("reports the TL;DR of a completed report", async () => {
3069
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3070
+ postMock.mockResolvedValue(
3071
+ structuredResponse({ analysisTldr: TLDR }) as never,
3072
+ );
3073
+
3074
+ renderPanel({ onReportSummaryChange });
3075
+ await flush();
3076
+
3077
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
3078
+ expect(nonNullCalls(onReportSummaryChange)).toEqual([TLDR]);
3079
+ });
3080
+
3081
+ test("falls back to the report's Summary as plain text without a TL;DR", async () => {
3082
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3083
+ postMock.mockResolvedValue(structuredResponse() as never);
3084
+
3085
+ renderPanel({ onReportSummaryChange });
3086
+ await flush();
3087
+
3088
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(REPORT_SUMMARY);
3089
+ });
3090
+
3091
+ test("bounds a long Summary", async () => {
3092
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3093
+ postMock.mockResolvedValue(
3094
+ completedResponse({
3095
+ analysisMarkdown: `**Summary** — ${"pool exhausted ".repeat(60)}\n\n**Root cause** — a deploy.`,
3096
+ }) as never,
3097
+ );
3098
+
3099
+ renderPanel({ onReportSummaryChange });
3100
+ await flush();
3101
+
3102
+ const summary: string = nonNullCalls(onReportSummaryChange)[0] as string;
3103
+ // Bounded by the analysisTldr column; the header clamps it on screen.
3104
+ expect(summary.length).toBeLessThanOrEqual(500);
3105
+ expect(summary.length).toBeGreaterThan(280);
3106
+ expect(summary.endsWith("…")).toBe(true);
3107
+ });
3108
+
3109
+ test("reports a TL;DR at the server's 320-character cap whole", async () => {
3110
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3111
+ const longTldr: string =
3112
+ "checkout-api release 2026.09.14-2 restarted at 17:52:04 with DB_POOL_MAX=10 instead of 40, so requests waited up to 2s in pg.pool.connect for an orders-db connection and p95 latency rose from ~310 ms to 2.35 s (db.client.connections.usage pinned at 10/10). Rolling back to 2026.09.14-1 cleared it, as in #1017 and #1029.";
3113
+
3114
+ expect(longTldr).toHaveLength(320);
3115
+ postMock.mockResolvedValue(
3116
+ structuredResponse({ analysisTldr: longTldr }) as never,
3117
+ );
3118
+
3119
+ renderPanel({ onReportSummaryChange });
3120
+ await flush();
3121
+
3122
+ expect(nonNullCalls(onReportSummaryChange)).toEqual([longTldr]);
3123
+ });
3124
+
3125
+ test("reports null when a report has neither a TL;DR nor a Summary", async () => {
3126
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3127
+ postMock.mockResolvedValue(completedResponse() as never);
3128
+
3129
+ renderPanel({ onReportSummaryChange });
3130
+ await flush();
3131
+
3132
+ expect(onReportSummaryChange).toHaveBeenCalledWith(null);
3133
+ expect(nonNullCalls(onReportSummaryChange)).toEqual([]);
3134
+ });
3135
+
3136
+ test("reports null while the run is active or the report is pending", async () => {
3137
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3138
+ postMock
3139
+ .mockResolvedValueOnce(
3140
+ successfulResponse(
3141
+ investigationPayload({
3142
+ status: AIRunStatus.Running,
3143
+ analysisTldr: TLDR,
3144
+ }),
3145
+ ) as never,
3146
+ )
3147
+ .mockResolvedValueOnce(
3148
+ completedResponse({
3149
+ analysisMarkdown: null,
3150
+ analysisTldr: TLDR,
3151
+ isAnalysisPending: true,
3152
+ }) as never,
3153
+ )
3154
+ .mockResolvedValue(structuredResponse({ analysisTldr: TLDR }) as never);
3155
+
3156
+ renderPanel({ onReportSummaryChange });
3157
+ await flush();
3158
+ await advanceFastPolls();
3159
+
3160
+ expect(nonNullCalls(onReportSummaryChange)).toEqual([]);
3161
+
3162
+ await advanceFastPolls();
3163
+
3164
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
3165
+ });
3166
+
3167
+ test("does not repeat an unchanged summary across polls", async () => {
3168
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3169
+ postMock.mockResolvedValue(
3170
+ structuredResponse({ analysisTldr: TLDR }) as never,
3171
+ );
3172
+
3173
+ renderPanel({ onReportSummaryChange });
3174
+ await flush();
3175
+ const callsAfterLoad: number = onReportSummaryChange.mock.calls.length;
3176
+
3177
+ await tick(SETTLED_POLL_INTERVAL_MS);
3178
+ await tick(SETTLED_POLL_INTERVAL_MS);
3179
+
3180
+ expect(investigationPostCount()).toBe(3);
3181
+ expect(onReportSummaryChange).toHaveBeenCalledTimes(callsAfterLoad);
3182
+ });
3183
+
3184
+ test("reports null the moment the subject changes, then the new summary", async () => {
3185
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3186
+ const nextSubject: Deferred<ApiResponse> = createDeferred<ApiResponse>();
3187
+ const nextTldr: string = "The webhook signer rotated its key.";
3188
+ postMock
3189
+ .mockResolvedValueOnce(
3190
+ structuredResponse({ analysisTldr: TLDR }) as never,
3191
+ )
3192
+ .mockReturnValueOnce(nextSubject.promise as never);
3193
+
3194
+ const view: ReturnType<typeof render> = renderPanel({
3195
+ onReportSummaryChange,
3196
+ });
3197
+ await flush();
3198
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
3199
+
3200
+ view.rerender(
3201
+ <InvestigationPanel
3202
+ subjectType="alert"
3203
+ subjectId={ALERT_ID}
3204
+ onReportSummaryChange={onReportSummaryChange}
3205
+ />,
3206
+ );
3207
+ await flush();
3208
+
3209
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(null);
3210
+
3211
+ await resolveDeferred(
3212
+ nextSubject,
3213
+ structuredResponse({ runId: NEXT_RUN_ID, analysisTldr: nextTldr }),
3214
+ );
3215
+
3216
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(nextTldr);
3217
+ });
3218
+
3219
+ test("reports null when the report disappears", async () => {
3220
+ const onReportSummaryChange: MockFunction = getJestMockFunction();
3221
+ postMock
3222
+ .mockResolvedValueOnce(
3223
+ structuredResponse({ analysisTldr: TLDR }) as never,
3224
+ )
3225
+ .mockResolvedValue(
3226
+ structuredResponse({
3227
+ analysisMarkdown: null,
3228
+ analysisTldr: TLDR,
3229
+ }) as never,
3230
+ );
3231
+
3232
+ renderPanel({ onReportSummaryChange });
3233
+ await flush();
3234
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
3235
+
3236
+ await tick(SETTLED_POLL_INTERVAL_MS);
3237
+
3238
+ expect(onReportSummaryChange).toHaveBeenLastCalledWith(null);
3239
+ });
3240
+
3241
+ test("uses the latest callback without re-reporting", async () => {
3242
+ const first: MockFunction = getJestMockFunction();
3243
+ const second: MockFunction = getJestMockFunction();
3244
+ postMock.mockResolvedValue(
3245
+ structuredResponse({ analysisTldr: TLDR }) as never,
3246
+ );
3247
+
3248
+ const view: ReturnType<typeof render> = renderPanel({
3249
+ onReportSummaryChange: first,
3250
+ });
3251
+ await flush();
3252
+ expect(first).toHaveBeenLastCalledWith(TLDR);
3253
+
3254
+ view.rerender(
3255
+ <InvestigationPanel
3256
+ subjectType="incident"
3257
+ subjectId={INCIDENT_ID}
3258
+ onReportSummaryChange={second}
3259
+ />,
3260
+ );
3261
+ await flush();
3262
+ expect(second).not.toHaveBeenCalled();
3263
+
3264
+ postMock.mockResolvedValue(
3265
+ structuredResponse({ analysisTldr: "A newer summary." }) as never,
3266
+ );
3267
+ await tick(SETTLED_POLL_INTERVAL_MS);
3268
+
3269
+ expect(second).toHaveBeenLastCalledWith("A newer summary.");
3270
+ });
3271
+ });
3272
+
3273
+ /*
3274
+ * The header shows a responder's verdict next to the report's summary, so the
3275
+ * panel reports it on the summary's terms: once per change, null until a
3276
+ * report is on screen, and afresh for every subject.
3277
+ */
3278
+ describe("InvestigationPanel verdict callback", () => {
3279
+ function reportedVerdicts(callback: MockFunction): Array<unknown> {
3280
+ return callback.mock.calls.map((call: Array<unknown>): unknown => {
3281
+ return call[0];
3282
+ });
3283
+ }
3284
+
3285
+ function nonNullVerdicts(callback: MockFunction): Array<unknown> {
3286
+ return reportedVerdicts(callback).filter((value: unknown): boolean => {
3287
+ return value !== null;
3288
+ });
3289
+ }
3290
+
3291
+ test.each(Object.values(AIRunHumanVerdict))(
3292
+ "reports a %s verdict saved with the completed report",
3293
+ async (verdict: AIRunHumanVerdict) => {
3294
+ const onVerdictChange: MockFunction = getJestMockFunction();
3295
+ postMock.mockResolvedValue(
3296
+ structuredResponse({ humanVerdict: verdict }) as never,
3297
+ );
3298
+
3299
+ renderPanel({ onVerdictChange });
3300
+ await flush();
3301
+
3302
+ expect(onVerdictChange).toHaveBeenLastCalledWith(verdict);
3303
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([verdict]);
3304
+ },
3305
+ );
3306
+
3307
+ test("reports null for a report nobody has rated", async () => {
3308
+ const onVerdictChange: MockFunction = getJestMockFunction();
3309
+ postMock.mockResolvedValue(structuredResponse() as never);
3310
+
3311
+ renderPanel({ onVerdictChange });
3312
+ await flush();
3313
+
3314
+ expect(onVerdictChange).toHaveBeenCalledWith(null);
3315
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
3316
+ });
3317
+
3318
+ test("reports no verdict it cannot name", async () => {
3319
+ const onVerdictChange: MockFunction = getJestMockFunction();
3320
+ postMock.mockResolvedValue(
3321
+ structuredResponse({ humanVerdict: "Edited" }) as never,
3322
+ );
3323
+
3324
+ renderPanel({ onVerdictChange });
3325
+ await flush();
3326
+
3327
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
3328
+ });
3329
+
3330
+ test.each([
3331
+ [
3332
+ "while a new run is in flight",
3333
+ (): ApiResponse => {
3334
+ return successfulResponse(
3335
+ investigationPayload({
3336
+ status: AIRunStatus.Running,
3337
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3338
+ }),
3339
+ );
3340
+ },
3341
+ ],
3342
+ [
3343
+ "while the report is still being prepared",
3344
+ (): ApiResponse => {
3345
+ return completedResponse({
3346
+ analysisMarkdown: null,
3347
+ isAnalysisPending: true,
3348
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3349
+ });
3350
+ },
3351
+ ],
3352
+ ])(
3353
+ "reports no verdict %s",
3354
+ async (_label: string, response: () => ApiResponse) => {
3355
+ const onVerdictChange: MockFunction = getJestMockFunction();
3356
+ postMock.mockResolvedValue(response() as never);
3357
+
3358
+ renderPanel({ onVerdictChange });
3359
+ await flush();
3360
+
3361
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
3362
+ },
3363
+ );
3364
+
3365
+ test("reports a rating the moment it is made, and a changed one", async () => {
3366
+ const onVerdictChange: MockFunction = getJestMockFunction();
3367
+ postMock
3368
+ .mockResolvedValueOnce(structuredResponse() as never)
3369
+ .mockResolvedValueOnce(successfulResponse({}) as never)
3370
+ .mockResolvedValueOnce(successfulResponse({}) as never);
3371
+
3372
+ renderPanel({ onVerdictChange });
3373
+ await flush();
3374
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
3375
+
3376
+ fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
3377
+ // Optimistic, like the panel's own pill: before the save resolves.
3378
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3379
+ AIRunHumanVerdict.Confirmed,
3380
+ );
3381
+ await flush();
3382
+
3383
+ fireEvent.click(screen.getByRole("button", { name: "Change" }));
3384
+ fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
3385
+ await flush();
3386
+
3387
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([
3388
+ AIRunHumanVerdict.Confirmed,
3389
+ AIRunHumanVerdict.Rejected,
3390
+ ]);
3391
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3392
+ AIRunHumanVerdict.Rejected,
3393
+ );
3394
+ });
3395
+
3396
+ test("takes a rating back out when the save fails", async () => {
3397
+ const onVerdictChange: MockFunction = getJestMockFunction();
3398
+ postMock
3399
+ .mockResolvedValueOnce(structuredResponse() as never)
3400
+ .mockResolvedValueOnce(
3401
+ new HTTPErrorResponse(
3402
+ 500,
3403
+ { message: "Verdict storage is unavailable." },
3404
+ {},
3405
+ ) as never,
3406
+ );
3407
+
3408
+ renderPanel({ onVerdictChange });
3409
+ await flush();
3410
+ fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
3411
+ await flush();
3412
+
3413
+ expect(screen.getByRole("alert")).toHaveTextContent(
3414
+ "Could not save your verdict",
3415
+ );
3416
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([
3417
+ AIRunHumanVerdict.Rejected,
3418
+ ]);
3419
+ expect(onVerdictChange).toHaveBeenLastCalledWith(null);
3420
+ });
3421
+
3422
+ test("a poll started before a rating saved cannot flip the reported verdict", async () => {
3423
+ const onVerdictChange: MockFunction = getJestMockFunction();
3424
+ const stalePoll: Deferred<ApiResponse> = createDeferred<ApiResponse>();
3425
+ postMock
3426
+ .mockResolvedValueOnce(structuredResponse() as never)
3427
+ .mockReturnValueOnce(stalePoll.promise as never)
3428
+ .mockResolvedValueOnce(successfulResponse({}) as never);
3429
+
3430
+ renderPanel({ onVerdictChange });
3431
+ await flush();
3432
+ await tick(SETTLED_POLL_INTERVAL_MS);
3433
+ expect(postMock).toHaveBeenCalledTimes(2);
3434
+
3435
+ fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
3436
+ await flush();
3437
+ const callsAfterRating: number = onVerdictChange.mock.calls.length;
3438
+
3439
+ await resolveDeferred(
3440
+ stalePoll,
3441
+ structuredResponse({ humanVerdict: null }),
3442
+ );
3443
+
3444
+ expect(onVerdictChange).toHaveBeenCalledTimes(callsAfterRating);
3445
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3446
+ AIRunHumanVerdict.Confirmed,
3447
+ );
3448
+ });
3449
+
3450
+ test("follows a verdict another responder saves", async () => {
3451
+ const onVerdictChange: MockFunction = getJestMockFunction();
3452
+ postMock
3453
+ .mockResolvedValueOnce(structuredResponse() as never)
3454
+ .mockResolvedValue(
3455
+ structuredResponse({
3456
+ humanVerdict: AIRunHumanVerdict.Rejected,
3457
+ }) as never,
3458
+ );
3459
+
3460
+ renderPanel({ onVerdictChange });
3461
+ await flush();
3462
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
3463
+
3464
+ await tick(SETTLED_POLL_INTERVAL_MS);
3465
+
3466
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3467
+ AIRunHumanVerdict.Rejected,
3468
+ );
3469
+ });
3470
+
3471
+ test("does not repeat an unchanged verdict across polls", async () => {
3472
+ const onVerdictChange: MockFunction = getJestMockFunction();
3473
+ postMock.mockResolvedValue(
3474
+ structuredResponse({
3475
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3476
+ }) as never,
3477
+ );
3478
+
3479
+ renderPanel({ onVerdictChange });
3480
+ await flush();
3481
+ const callsAfterLoad: number = onVerdictChange.mock.calls.length;
3482
+
3483
+ await tick(SETTLED_POLL_INTERVAL_MS);
3484
+ await tick(SETTLED_POLL_INTERVAL_MS);
3485
+
3486
+ expect(investigationPostCount()).toBe(3);
3487
+ expect(onVerdictChange).toHaveBeenCalledTimes(callsAfterLoad);
3488
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([
3489
+ AIRunHumanVerdict.Confirmed,
3490
+ ]);
3491
+ });
3492
+
3493
+ test("drops the verdict when a new run starts", async () => {
3494
+ const onVerdictChange: MockFunction = getJestMockFunction();
3495
+ postMock
3496
+ .mockResolvedValueOnce(
3497
+ structuredResponse({
3498
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3499
+ }) as never,
3500
+ )
3501
+ .mockResolvedValue(
3502
+ successfulResponse(
3503
+ investigationPayload({
3504
+ status: AIRunStatus.Queued,
3505
+ runId: NEXT_RUN_ID,
3506
+ }),
3507
+ ) as never,
3508
+ );
3509
+
3510
+ renderPanel({ onVerdictChange });
3511
+ await flush();
3512
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3513
+ AIRunHumanVerdict.Confirmed,
3514
+ );
3515
+
3516
+ await tick(SETTLED_POLL_INTERVAL_MS);
3517
+
3518
+ expect(onVerdictChange).toHaveBeenLastCalledWith(null);
3519
+ });
3520
+
3521
+ test("reports null the moment the subject changes, then the new verdict", async () => {
3522
+ const onVerdictChange: MockFunction = getJestMockFunction();
3523
+ const nextSubject: Deferred<ApiResponse> = createDeferred<ApiResponse>();
3524
+ postMock
3525
+ .mockResolvedValueOnce(
3526
+ structuredResponse({
3527
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3528
+ }) as never,
3529
+ )
3530
+ .mockReturnValueOnce(nextSubject.promise as never);
3531
+
3532
+ const view: ReturnType<typeof render> = renderPanel({ onVerdictChange });
3533
+ await flush();
3534
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3535
+ AIRunHumanVerdict.Confirmed,
3536
+ );
3537
+
3538
+ view.rerender(
3539
+ <InvestigationPanel
3540
+ subjectType="alert"
3541
+ subjectId={ALERT_ID}
3542
+ onVerdictChange={onVerdictChange}
3543
+ />,
3544
+ );
3545
+ await flush();
3546
+
3547
+ // Before the alert's report arrives, and without a stale confirmation.
3548
+ expect(onVerdictChange).toHaveBeenLastCalledWith(null);
3549
+
3550
+ await resolveDeferred(
3551
+ nextSubject,
3552
+ structuredResponse({
3553
+ runId: NEXT_RUN_ID,
3554
+ humanVerdict: AIRunHumanVerdict.Rejected,
3555
+ }),
3556
+ );
3557
+
3558
+ expect(onVerdictChange).toHaveBeenLastCalledWith(
3559
+ AIRunHumanVerdict.Rejected,
3560
+ );
3561
+ expect(nonNullVerdicts(onVerdictChange)).toEqual([
3562
+ AIRunHumanVerdict.Confirmed,
3563
+ AIRunHumanVerdict.Rejected,
3564
+ ]);
3565
+ });
3566
+
3567
+ test("uses the latest callback without re-reporting", async () => {
3568
+ const first: MockFunction = getJestMockFunction();
3569
+ const second: MockFunction = getJestMockFunction();
3570
+ postMock.mockResolvedValue(
3571
+ structuredResponse({
3572
+ humanVerdict: AIRunHumanVerdict.Confirmed,
3573
+ }) as never,
3574
+ );
3575
+
3576
+ const view: ReturnType<typeof render> = renderPanel({
3577
+ onVerdictChange: first,
3578
+ });
3579
+ await flush();
3580
+ expect(first).toHaveBeenLastCalledWith(AIRunHumanVerdict.Confirmed);
3581
+ const firstCallCount: number = first.mock.calls.length;
3582
+
3583
+ view.rerender(
3584
+ <InvestigationPanel
3585
+ subjectType="incident"
3586
+ subjectId={INCIDENT_ID}
3587
+ onVerdictChange={second}
3588
+ />,
3589
+ );
3590
+ await flush();
3591
+ expect(second).not.toHaveBeenCalled();
3592
+
3593
+ postMock.mockResolvedValue(
3594
+ structuredResponse({ humanVerdict: AIRunHumanVerdict.Rejected }) as never,
3595
+ );
3596
+ await tick(SETTLED_POLL_INTERVAL_MS);
3597
+
3598
+ expect(reportedVerdicts(second)).toEqual([AIRunHumanVerdict.Rejected]);
3599
+ expect(first).toHaveBeenCalledTimes(firstCallCount);
3600
+ });
3601
+ });