@oneuptime/common 11.5.4 → 11.5.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 (539) hide show
  1. package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +56 -45
  2. package/Models/DatabaseModels/AIInsight.ts +748 -0
  3. package/Models/DatabaseModels/AIRun.ts +262 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +42 -0
  5. package/Models/DatabaseModels/GlobalConfig.ts +105 -0
  6. package/Models/DatabaseModels/Index.ts +4 -8
  7. package/Models/DatabaseModels/InstanceHealthLog.ts +277 -0
  8. package/Models/DatabaseModels/LlmLog.ts +33 -0
  9. package/Models/DatabaseModels/Project.ts +123 -6
  10. package/Models/DatabaseModels/Runbook.ts +1 -1
  11. package/Models/DatabaseModels/User.ts +47 -0
  12. package/Server/API/AIAgentDataAPI.ts +802 -140
  13. package/Server/API/AIAgentTaskAPI.ts +132 -69
  14. package/Server/API/AIAgentTaskLogAPI.ts +65 -41
  15. package/Server/API/AIAgentTaskPullRequestAPI.ts +41 -0
  16. package/Server/API/AIInsightAPI.ts +220 -0
  17. package/Server/API/AIInvestigationAPI.ts +363 -1
  18. package/Server/API/CodeFixRunAPI.ts +251 -0
  19. package/Server/API/GitHubAPI.ts +246 -3
  20. package/Server/API/TelemetryExceptionAPI.ts +193 -48
  21. package/Server/EnvironmentConfig.ts +1 -1
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.ts +26 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.ts +73 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.ts +29 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.ts +31 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.ts +51 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.ts +25 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.ts +47 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.ts +53 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.ts +31 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.ts +37 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.ts +25 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.ts +75 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.ts +37 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.ts +203 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.ts +163 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1784048917994-AddCreatedByUserToUser.ts +23 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +32 -0
  39. package/Server/Infrastructure/Queue.ts +82 -4
  40. package/Server/Infrastructure/Semaphore.ts +62 -1
  41. package/Server/Middleware/MasterAdminAuthorization.ts +37 -0
  42. package/Server/Middleware/ProjectAuthorization.ts +40 -15
  43. package/Server/Services/AIAgentService.ts +32 -0
  44. package/Server/Services/AIAgentTaskPullRequestService.ts +117 -0
  45. package/Server/Services/AIInsightService.ts +174 -0
  46. package/Server/Services/AIRunEventService.ts +63 -0
  47. package/Server/Services/AIRunService.ts +259 -1
  48. package/Server/Services/AIService.ts +249 -7
  49. package/Server/Services/AlertService.ts +4 -4
  50. package/Server/Services/CodeRepositoryService.ts +209 -0
  51. package/Server/Services/GlobalConfigService.ts +148 -0
  52. package/Server/Services/IncidentService.ts +183 -38
  53. package/Server/Services/IncidentStateTimelineService.ts +24 -4
  54. package/Server/Services/Index.ts +4 -4
  55. package/Server/Services/{AIAgentTaskLogService.ts → InstanceHealthLogService.ts} +1 -1
  56. package/Server/Services/LlmLogService.ts +27 -0
  57. package/Server/Services/LlmProviderService.ts +108 -0
  58. package/Server/Services/MetricBaselineService.ts +123 -0
  59. package/Server/Services/MonitorService.ts +15 -0
  60. package/Server/Services/TeamMemberService.ts +2 -0
  61. package/Server/Services/TelemetryExceptionService.ts +323 -116
  62. package/Server/Services/TraceAggregationService.ts +176 -0
  63. package/Server/Services/UserService.ts +10 -0
  64. package/Server/Types/Workflow/ComponentCode.ts +6 -0
  65. package/Server/Types/Workflow/Components/AI/GenerateText.ts +326 -0
  66. package/Server/Types/Workflow/Components/Index.ts +2 -0
  67. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +1 -1
  68. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +71 -0
  69. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +243 -0
  70. package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +131 -0
  71. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +148 -0
  72. package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +117 -0
  73. package/Server/Utils/AI/Eval/EvalCorpus.ts +369 -0
  74. package/Server/Utils/AI/Eval/EvalScores.ts +172 -0
  75. package/Server/Utils/AI/Eval/ReplayInvestigation.ts +87 -0
  76. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +676 -0
  77. package/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.ts → SRE/AIInvestigationEngine.ts} +58 -37
  78. package/Server/Utils/AI/{Sentinel/SentinelMemory.ts → SRE/AIMemory.ts} +3 -3
  79. package/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.ts +50 -20
  80. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +293 -0
  81. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +115 -0
  82. package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +223 -0
  83. package/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.ts +71 -21
  84. package/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.ts +8 -8
  85. package/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.ts +364 -0
  86. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +317 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/Index.ts +27 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts +221 -0
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +238 -0
  90. package/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.ts +521 -0
  91. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +242 -0
  92. package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +290 -0
  93. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +283 -0
  94. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +242 -0
  95. package/Server/Utils/AI/SRE/Insights/Triage.ts +162 -0
  96. package/Server/Utils/AI/SRE/Insights/Types.ts +49 -0
  97. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +212 -0
  98. package/Server/Utils/AI/SRE/InvestigationGrader.ts +282 -0
  99. package/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.ts +114 -19
  100. package/Server/Utils/AI/{Sentinel → SRE}/README.md +4 -4
  101. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +172 -0
  102. package/Server/Utils/AI/Toolbox/{SentinelActionTools.ts → AIActionTools.ts} +22 -1
  103. package/Server/Utils/AI/Toolbox/Index.ts +2 -2
  104. package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +526 -0
  105. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +319 -1
  106. package/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.ts +221 -0
  107. package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +571 -0
  108. package/Server/Utils/Execute.ts +2 -1
  109. package/Server/Utils/LLM/LLMService.ts +160 -30
  110. package/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts +152 -0
  111. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +29 -0
  112. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +16 -6
  113. package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +14 -0
  114. package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +14 -3
  115. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +130 -12
  116. package/Tests/Server/Infrastructure/Queue.test.ts +227 -0
  117. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +159 -0
  118. package/Tests/Server/Services/AIAgentTaskPullRequestOutcomeStats.test.ts +154 -0
  119. package/Tests/Server/Services/AIInsightService.test.ts +324 -0
  120. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +401 -0
  121. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +161 -0
  122. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +95 -5
  123. package/Tests/Server/Services/AIServiceProjectAccess.test.ts +259 -0
  124. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +249 -0
  125. package/Tests/Server/Services/FixPerformanceTaskTrigger.test.ts +274 -0
  126. package/Tests/Server/Services/GlobalConfigService.test.ts +80 -0
  127. package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +1 -1
  128. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +313 -0
  129. package/Tests/Server/Services/LlmProviderProjectOwned.test.ts +132 -0
  130. package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +405 -0
  131. package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +322 -0
  132. package/Tests/Server/Services/TraceServiceLatencyProfile.test.ts +278 -0
  133. package/Tests/Server/Types/Workflow/Components/AIGenerateText.test.ts +722 -0
  134. package/Tests/Server/Utils/AI/{SentinelAlertGating.test.ts → AIAlertGating.test.ts} +19 -19
  135. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +362 -0
  136. package/Tests/Server/Utils/AI/{SentinelInvestigationQueue.test.ts → AIInvestigationQueue.test.ts} +19 -19
  137. package/Tests/Server/Utils/AI/CodeAgentWorkspaceGuard.test.ts +138 -0
  138. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +335 -0
  139. package/Tests/Server/Utils/AI/CodeFixRunQueue.test.ts +134 -0
  140. package/Tests/Server/Utils/AI/EvalCorpus.test.ts +209 -0
  141. package/Tests/Server/Utils/AI/EvalScores.test.ts +343 -0
  142. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +218 -0
  143. package/Tests/Server/Utils/AI/Insights/ErrorLogSpikeDetector.test.ts +437 -0
  144. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +287 -0
  145. package/Tests/Server/Utils/AI/Insights/InsightDetectorsIndex.test.ts +34 -0
  146. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +572 -0
  147. package/Tests/Server/Utils/AI/Insights/InsightNeverThrowsHardening.test.ts +344 -0
  148. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +720 -0
  149. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +467 -0
  150. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +370 -0
  151. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +210 -0
  152. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +221 -0
  153. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +328 -0
  154. package/Tests/Server/Utils/AI/Insights/MetricBaselineDrift.test.ts +182 -0
  155. package/Tests/Server/Utils/AI/Insights/MetricDriftDetector.test.ts +280 -0
  156. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +259 -0
  157. package/Tests/Server/Utils/AI/Insights/TraceLatencyRegressionDetector.test.ts +770 -0
  158. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +343 -0
  159. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +307 -0
  160. package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +170 -0
  161. package/Tests/Server/Utils/AI/SpanTreeAnalyzer.test.ts +559 -0
  162. package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +158 -0
  163. package/Tests/Server/Utils/GitHubCheckRunsConclusion.test.ts +100 -0
  164. package/Tests/Server/Utils/GitHubPullRequestStateMapping.test.ts +50 -0
  165. package/Tests/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.test.ts +266 -0
  166. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +553 -0
  167. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +590 -0
  168. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageFormatterUnits.test.ts +254 -0
  169. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +821 -0
  170. package/Tests/Server/Utils/ServiceRepoLinkSuggester.test.ts +167 -0
  171. package/Tests/Server/Utils/StackTraceRepoResolver.test.ts +527 -0
  172. package/Tests/Types/AI/AIChatPermissionMode.test.ts +112 -0
  173. package/Tests/Types/AI/CodeFixTaskType.test.ts +152 -0
  174. package/Tests/Types/AI/FixPullRequestCiStatus.test.ts +181 -0
  175. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +110 -0
  176. package/Tests/Types/Monitor/SqlDatabaseType.test.ts +55 -0
  177. package/Tests/Types/Workflow/AIGenerateTextMetadata.test.ts +180 -0
  178. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +168 -0
  179. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +523 -0
  180. package/Types/AI/AIChatTypes.ts +8 -0
  181. package/Types/AI/AIInsightEvidence.ts +77 -0
  182. package/Types/AI/AIInsightHumanVerdict.ts +15 -0
  183. package/Types/AI/AIInsightSeverity.ts +13 -0
  184. package/Types/AI/AIInsightStatus.ts +38 -0
  185. package/Types/AI/AIInsightType.ts +41 -0
  186. package/Types/AI/AIRunAutoGrade.ts +18 -0
  187. package/Types/AI/AIRunEventType.ts +5 -0
  188. package/Types/AI/AIRunHumanVerdict.ts +17 -0
  189. package/Types/AI/AIRunType.ts +6 -0
  190. package/Types/AI/CodeFixTaskContext.ts +88 -0
  191. package/Types/AI/CodeFixTaskType.ts +132 -0
  192. package/Types/AI/FixPullRequestCiStatus.ts +132 -0
  193. package/Types/BaseDatabase/AggregationIntervalUtil.ts +67 -0
  194. package/Types/Incident/IncidentMetricType.ts +7 -0
  195. package/Types/Monitor/CriteriaFilter.ts +8 -0
  196. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  197. package/Types/Monitor/MonitorStep.ts +38 -0
  198. package/Types/Monitor/MonitorStepSqlMonitor.ts +141 -0
  199. package/Types/Monitor/MonitorType.ts +17 -0
  200. package/Types/Monitor/SqlDatabaseType.ts +49 -0
  201. package/Types/Monitor/SqlMonitor/SqlMonitorResponse.ts +28 -0
  202. package/Types/Permission.ts +11 -95
  203. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  204. package/Types/Runbook/RunbookStep.ts +26 -2
  205. package/Types/Runbook/RunbookStepType.ts +1 -0
  206. package/Types/Workflow/Component.ts +13 -0
  207. package/Types/Workflow/ComponentID.ts +1 -0
  208. package/Types/Workflow/Components/AI.ts +148 -0
  209. package/Types/Workflow/Components.ts +8 -0
  210. package/UI/Components/AI/GenerateFromAIModal.tsx +1 -1
  211. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +11 -0
  212. package/UI/Components/MoreMenu/MoreMenu.tsx +1 -1
  213. package/UI/Components/Table/Table.tsx +38 -2
  214. package/UI/Utils/TableColumnsToCsv.ts +385 -0
  215. package/Utils/Monitor/MonitorMetricType.ts +1 -0
  216. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +59 -45
  217. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
  218. package/build/dist/Models/DatabaseModels/AIInsight.js +795 -0
  219. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -0
  220. package/build/dist/Models/DatabaseModels/AIRun.js +274 -0
  221. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  222. package/build/dist/Models/DatabaseModels/CodeRepository.js +43 -0
  223. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  224. package/build/dist/Models/DatabaseModels/GlobalConfig.js +110 -0
  225. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  226. package/build/dist/Models/DatabaseModels/Index.js +4 -8
  227. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  228. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js +304 -0
  229. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js.map +1 -0
  230. package/build/dist/Models/DatabaseModels/LlmLog.js +35 -0
  231. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  232. package/build/dist/Models/DatabaseModels/Project.js +127 -6
  233. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  234. package/build/dist/Models/DatabaseModels/Runbook.js +1 -1
  235. package/build/dist/Models/DatabaseModels/Runbook.js.map +1 -1
  236. package/build/dist/Models/DatabaseModels/User.js +46 -0
  237. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  238. package/build/dist/Server/API/AIAgentDataAPI.js +568 -85
  239. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  240. package/build/dist/Server/API/AIAgentTaskAPI.js +100 -44
  241. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
  242. package/build/dist/Server/API/AIAgentTaskLogAPI.js +49 -25
  243. package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
  244. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +27 -0
  245. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -1
  246. package/build/dist/Server/API/AIInsightAPI.js +140 -0
  247. package/build/dist/Server/API/AIInsightAPI.js.map +1 -0
  248. package/build/dist/Server/API/AIInvestigationAPI.js +257 -1
  249. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  250. package/build/dist/Server/API/CodeFixRunAPI.js +181 -0
  251. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -0
  252. package/build/dist/Server/API/GitHubAPI.js +164 -2
  253. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  254. package/build/dist/Server/API/TelemetryExceptionAPI.js +148 -43
  255. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
  256. package/build/dist/Server/EnvironmentConfig.js +1 -1
  257. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  258. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js +23 -0
  259. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js.map +1 -0
  260. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js +32 -0
  261. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js.map +1 -0
  262. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js +16 -0
  263. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js.map +1 -0
  264. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js +16 -0
  265. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js.map +1 -0
  266. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js +24 -0
  267. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js.map +1 -0
  268. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js +16 -0
  269. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js.map +1 -0
  270. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js +24 -0
  271. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js.map +1 -0
  272. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js +24 -0
  273. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js.map +1 -0
  274. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js +24 -0
  275. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js.map +1 -0
  276. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js +18 -0
  277. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js.map +1 -0
  278. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js +18 -0
  279. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js.map +1 -0
  280. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js +32 -0
  281. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js.map +1 -0
  282. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js +18 -0
  283. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js.map +1 -0
  284. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js +125 -0
  285. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js.map +1 -0
  286. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js +62 -0
  287. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js.map +1 -0
  288. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784048917994-AddCreatedByUserToUser.js +18 -0
  289. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784048917994-AddCreatedByUserToUser.js.map +1 -0
  290. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +32 -0
  291. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  292. package/build/dist/Server/Infrastructure/Queue.js +73 -3
  293. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  294. package/build/dist/Server/Infrastructure/Semaphore.js +44 -1
  295. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  296. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +26 -0
  297. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  298. package/build/dist/Server/Middleware/ProjectAuthorization.js +40 -14
  299. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  300. package/build/dist/Server/Services/AIAgentService.js +29 -0
  301. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  302. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +78 -0
  303. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -1
  304. package/build/dist/Server/Services/AIInsightService.js +164 -0
  305. package/build/dist/Server/Services/AIInsightService.js.map +1 -0
  306. package/build/dist/Server/Services/AIRunEventService.js +49 -0
  307. package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
  308. package/build/dist/Server/Services/AIRunService.js +221 -0
  309. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  310. package/build/dist/Server/Services/AIService.js +198 -11
  311. package/build/dist/Server/Services/AIService.js.map +1 -1
  312. package/build/dist/Server/Services/AlertService.js +4 -4
  313. package/build/dist/Server/Services/AlertService.js.map +1 -1
  314. package/build/dist/Server/Services/CodeRepositoryService.js +180 -0
  315. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  316. package/build/dist/Server/Services/GlobalConfigService.js +84 -0
  317. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  318. package/build/dist/Server/Services/IncidentService.js +149 -37
  319. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  320. package/build/dist/Server/Services/IncidentStateTimelineService.js +24 -4
  321. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  322. package/build/dist/Server/Services/Index.js +4 -4
  323. package/build/dist/Server/Services/Index.js.map +1 -1
  324. package/build/dist/Server/Services/{AIAgentTaskLogService.js → InstanceHealthLogService.js} +2 -2
  325. package/build/dist/Server/Services/InstanceHealthLogService.js.map +1 -0
  326. package/build/dist/Server/Services/LlmLogService.js +23 -0
  327. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  328. package/build/dist/Server/Services/LlmProviderService.js +96 -0
  329. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  330. package/build/dist/Server/Services/MetricBaselineService.js +65 -0
  331. package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
  332. package/build/dist/Server/Services/MonitorService.js +9 -1
  333. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  334. package/build/dist/Server/Services/TeamMemberService.js +2 -0
  335. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  336. package/build/dist/Server/Services/TelemetryExceptionService.js +243 -82
  337. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  338. package/build/dist/Server/Services/TraceAggregationService.js +124 -0
  339. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  340. package/build/dist/Server/Services/UserService.js +8 -0
  341. package/build/dist/Server/Services/UserService.js.map +1 -1
  342. package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
  343. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js +240 -0
  344. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js.map +1 -0
  345. package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
  346. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  347. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +48 -0
  348. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -0
  349. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +174 -0
  350. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -0
  351. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +126 -0
  352. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js.map +1 -0
  353. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +131 -0
  354. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -0
  355. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +99 -0
  356. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -0
  357. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js +245 -0
  358. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js.map +1 -0
  359. package/build/dist/Server/Utils/AI/Eval/EvalScores.js +83 -0
  360. package/build/dist/Server/Utils/AI/Eval/EvalScores.js.map +1 -0
  361. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js +12 -0
  362. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js.map +1 -0
  363. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +439 -0
  364. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -0
  365. package/build/dist/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.js → SRE/AIInvestigationEngine.js} +47 -31
  366. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -0
  367. package/build/dist/Server/Utils/AI/{Sentinel/SentinelMemory.js → SRE/AIMemory.js} +5 -5
  368. package/build/dist/Server/Utils/AI/SRE/AIMemory.js.map +1 -0
  369. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.js +42 -19
  370. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +226 -0
  372. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -0
  373. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +100 -0
  374. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -0
  375. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +174 -0
  376. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -0
  377. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.js +60 -22
  378. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -0
  379. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.js +9 -9
  380. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -0
  381. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js +268 -0
  382. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js.map +1 -0
  383. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +226 -0
  384. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -0
  385. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js +26 -0
  386. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js.map +1 -0
  387. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js +159 -0
  388. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js.map +1 -0
  389. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +177 -0
  390. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -0
  391. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js +384 -0
  392. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js.map +1 -0
  393. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +180 -0
  394. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -0
  395. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +269 -0
  396. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js.map +1 -0
  397. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +231 -0
  398. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -0
  399. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +206 -0
  400. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -0
  401. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +121 -0
  402. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -0
  403. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js +2 -0
  404. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js.map +1 -0
  405. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +148 -0
  406. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +231 -0
  408. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -0
  409. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.js +102 -23
  410. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -0
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +167 -0
  412. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -0
  413. package/build/dist/Server/Utils/AI/Toolbox/{SentinelActionTools.js → AIActionTools.js} +18 -2
  414. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -0
  415. package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -2
  416. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  417. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +301 -0
  418. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -0
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +240 -2
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  421. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js +127 -0
  422. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js.map +1 -0
  423. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +336 -0
  424. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -0
  425. package/build/dist/Server/Utils/Execute.js.map +1 -1
  426. package/build/dist/Server/Utils/LLM/LLMService.js +125 -25
  427. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js +120 -0
  429. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js.map +1 -0
  430. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -0
  431. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +15 -7
  433. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +12 -1
  435. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +8 -3
  437. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +96 -12
  439. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  440. package/build/dist/Types/AI/AIInsightEvidence.js +2 -0
  441. package/build/dist/Types/AI/AIInsightEvidence.js.map +1 -0
  442. package/build/dist/Types/AI/AIInsightHumanVerdict.js +16 -0
  443. package/build/dist/Types/AI/AIInsightHumanVerdict.js.map +1 -0
  444. package/build/dist/Types/AI/AIInsightSeverity.js +14 -0
  445. package/build/dist/Types/AI/AIInsightSeverity.js.map +1 -0
  446. package/build/dist/Types/AI/AIInsightStatus.js +36 -0
  447. package/build/dist/Types/AI/AIInsightStatus.js.map +1 -0
  448. package/build/dist/Types/AI/AIInsightType.js +42 -0
  449. package/build/dist/Types/AI/AIInsightType.js.map +1 -0
  450. package/build/dist/Types/AI/AIRunAutoGrade.js +19 -0
  451. package/build/dist/Types/AI/AIRunAutoGrade.js.map +1 -0
  452. package/build/dist/Types/AI/AIRunEventType.js +5 -0
  453. package/build/dist/Types/AI/AIRunEventType.js.map +1 -1
  454. package/build/dist/Types/AI/AIRunHumanVerdict.js +18 -0
  455. package/build/dist/Types/AI/AIRunHumanVerdict.js.map +1 -0
  456. package/build/dist/Types/AI/AIRunType.js +6 -0
  457. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  458. package/build/dist/Types/AI/CodeFixTaskContext.js +29 -0
  459. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -0
  460. package/build/dist/Types/AI/CodeFixTaskType.js +122 -0
  461. package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -0
  462. package/build/dist/Types/AI/FixPullRequestCiStatus.js +102 -0
  463. package/build/dist/Types/AI/FixPullRequestCiStatus.js.map +1 -0
  464. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +55 -0
  465. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  466. package/build/dist/Types/Incident/IncidentMetricType.js +7 -0
  467. package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
  468. package/build/dist/Types/Monitor/CriteriaFilter.js +7 -0
  469. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  470. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  471. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  472. package/build/dist/Types/Monitor/MonitorStep.js +28 -0
  473. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  474. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +93 -0
  475. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -0
  476. package/build/dist/Types/Monitor/MonitorType.js +15 -0
  477. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  478. package/build/dist/Types/Monitor/SqlDatabaseType.js +47 -0
  479. package/build/dist/Types/Monitor/SqlDatabaseType.js.map +1 -0
  480. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js +2 -0
  481. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js.map +1 -0
  482. package/build/dist/Types/Permission.js +10 -84
  483. package/build/dist/Types/Permission.js.map +1 -1
  484. package/build/dist/Types/Runbook/RunbookStepType.js +1 -0
  485. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  486. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  487. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  488. package/build/dist/Types/Workflow/Components/AI.js +135 -0
  489. package/build/dist/Types/Workflow/Components/AI.js.map +1 -0
  490. package/build/dist/Types/Workflow/Components.js +7 -0
  491. package/build/dist/Types/Workflow/Components.js.map +1 -1
  492. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -1
  493. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  494. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +9 -0
  495. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  496. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +1 -1
  497. package/build/dist/UI/Components/Table/Table.js +28 -2
  498. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  499. package/build/dist/UI/Utils/TableColumnsToCsv.js +291 -0
  500. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -0
  501. package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  503. package/package.json +1 -1
  504. package/Models/DatabaseModels/AIAgentTask.ts +0 -660
  505. package/Models/DatabaseModels/AIAgentTaskLog.ts +0 -426
  506. package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +0 -399
  507. package/Models/DatabaseModels/ServiceCodeRepository.ts +0 -647
  508. package/Server/Services/AIAgentTaskService.ts +0 -240
  509. package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +0 -39
  510. package/Server/Services/ServiceCodeRepositoryService.ts +0 -55
  511. package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +0 -146
  512. package/Types/AI/AIAgentTaskMetadata.ts +0 -25
  513. package/Types/AI/AIAgentTaskType.ts +0 -40
  514. package/build/dist/Models/DatabaseModels/AIAgentTask.js +0 -691
  515. package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +0 -1
  516. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +0 -447
  517. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +0 -1
  518. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +0 -415
  519. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +0 -1
  520. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +0 -665
  521. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +0 -1
  522. package/build/dist/Server/Services/AIAgentTaskLogService.js.map +0 -1
  523. package/build/dist/Server/Services/AIAgentTaskService.js +0 -217
  524. package/build/dist/Server/Services/AIAgentTaskService.js.map +0 -1
  525. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +0 -36
  526. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +0 -1
  527. package/build/dist/Server/Services/ServiceCodeRepositoryService.js +0 -54
  528. package/build/dist/Server/Services/ServiceCodeRepositoryService.js.map +0 -1
  529. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +0 -1
  530. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +0 -1
  531. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +0 -1
  532. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +0 -1
  533. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +0 -1
  534. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +0 -1
  535. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +0 -1
  536. package/build/dist/Types/AI/AIAgentTaskMetadata.js +0 -6
  537. package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +0 -1
  538. package/build/dist/Types/AI/AIAgentTaskType.js +0 -29
  539. package/build/dist/Types/AI/AIAgentTaskType.js.map +0 -1
@@ -0,0 +1,770 @@
1
+ import { afterEach, describe, expect, test } from "@jest/globals";
2
+ import TraceLatencyRegressionDetector, {
3
+ LATENCY_HIGH_SEVERITY_MULTIPLIER,
4
+ LATENCY_MAX_TRACE_SPANS,
5
+ LATENCY_MIN_OPERATION_SAMPLE_COUNT,
6
+ LATENCY_MIN_PRIOR_SAMPLE_COUNT,
7
+ LATENCY_MIN_RECENT_P99_MS,
8
+ LATENCY_SERVICE_LIMIT,
9
+ LATENCY_TOP_OPERATION_CANDIDATES,
10
+ LatencyRegressionDecision,
11
+ ServiceLatencyWindows,
12
+ } from "../../../../../Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector";
13
+ import { InsightCandidate } from "../../../../../Server/Utils/AI/SRE/Insights/Types";
14
+ import TraceAggregationService, {
15
+ ServiceLatencyProfile,
16
+ ServiceLatencyProfileRow,
17
+ TraceAnalyticsTopItem,
18
+ } from "../../../../../Server/Services/TraceAggregationService";
19
+ import SpanService from "../../../../../Server/Services/SpanService";
20
+ import ServiceService from "../../../../../Server/Services/ServiceService";
21
+ import Span from "../../../../../Models/AnalyticsModels/Span";
22
+ import Service from "../../../../../Models/DatabaseModels/Service";
23
+ import { AnalyzableSpan } from "../../../../../Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer";
24
+ import AIInsightSeverity from "../../../../../Types/AI/AIInsightSeverity";
25
+ import AIInsightType from "../../../../../Types/AI/AIInsightType";
26
+ import InBetween from "../../../../../Types/BaseDatabase/InBetween";
27
+ import SortOrder from "../../../../../Types/BaseDatabase/SortOrder";
28
+ import ObjectID from "../../../../../Types/ObjectID";
29
+
30
+ /*
31
+ * Invariant under test: the TraceLatencyRegression detector fires exactly
32
+ * when a service's recent-hour p99 is >= 1000ms AND >= 2x its own prior-24h
33
+ * p99 AND the prior window has >= 100 spans (High at 4x) — and ONLY then
34
+ * drills into a representative trace (slowest CREDIBLE operation → slowest
35
+ * span → whole trace → deterministic span-tree findings + code locations,
36
+ * with correct ns→ms conversion), storing the drilled evidence on the
37
+ * candidate because span retention is short. No LLM is ever involved.
38
+ *
39
+ * Two properties the whole lane's noise budget rests on, pinned here:
40
+ * 1. Stage 1 reads the PROJECTION-served profile query, never the
41
+ * full-scan analytics table — and a possibly-partial profile (the
42
+ * execution cap firing under timeout_overflow_mode='break') files
43
+ * NOTHING rather than comparing a truncated window to a whole one.
44
+ * 2. The drilled operation — which is part of the dedupe fingerprint —
45
+ * is chosen deterministically and only from operations with real
46
+ * traffic behind them, so one ongoing regression stays ONE insight.
47
+ */
48
+
49
+ const projectId: ObjectID = ObjectID.generate();
50
+ const entityId: string = ObjectID.generate().toString();
51
+ const now: Date = new Date("2026-07-14T12:00:00.000Z");
52
+ const oneHourAgo: Date = new Date("2026-07-14T11:00:00.000Z");
53
+ const twentyFiveHoursAgo: Date = new Date("2026-07-13T11:00:00.000Z");
54
+
55
+ function profileRow(input: {
56
+ entityId: string;
57
+ count: number;
58
+ p99Ms: number;
59
+ }): ServiceLatencyProfileRow {
60
+ return {
61
+ primaryEntityId: input.entityId,
62
+ count: input.count,
63
+ p99DurationMs: input.p99Ms,
64
+ };
65
+ }
66
+
67
+ function profile(rows: Array<ServiceLatencyProfileRow>): ServiceLatencyProfile {
68
+ return { rows, isPartial: false };
69
+ }
70
+
71
+ function topItem(input: {
72
+ value: string;
73
+ p99Ms: number;
74
+ count: number;
75
+ }): TraceAnalyticsTopItem {
76
+ return {
77
+ value: input.value,
78
+ metricValue: input.p99Ms,
79
+ count: input.count,
80
+ };
81
+ }
82
+
83
+ /*
84
+ * A two-span trace engineered to trip the analyzer's dominant-span rule:
85
+ * the child covers 95% of the 1000ms trace with no children of its own, so
86
+ * its SELF time dominates. Times are NANOSECONDS, as stored on Span rows.
87
+ */
88
+ function fakeTraceSpans(): Array<Span> {
89
+ return [
90
+ {
91
+ spanId: "root",
92
+ parentSpanId: "",
93
+ name: "GET /users/42",
94
+ startTimeUnixNano: 0,
95
+ endTimeUnixNano: 1_000_000_000,
96
+ durationUnixNano: 1_000_000_000,
97
+ attributes: {},
98
+ },
99
+ {
100
+ spanId: "slow-child",
101
+ parentSpanId: "root",
102
+ name: "SELECT users",
103
+ startTimeUnixNano: 0,
104
+ endTimeUnixNano: 950_000_000,
105
+ durationUnixNano: 950_000_000,
106
+ attributes: {
107
+ "code.filepath": "src/db.ts",
108
+ "code.function": "loadUsers",
109
+ "code.lineno": "42",
110
+ },
111
+ },
112
+ ] as unknown as Array<Span>;
113
+ }
114
+
115
+ describe("TraceLatencyRegressionDetector.evaluateRegression (pure decision matrix)", () => {
116
+ test("all thresholds exactly at their boundaries → regression at Medium", () => {
117
+ const decision: LatencyRegressionDecision =
118
+ TraceLatencyRegressionDetector.evaluateRegression({
119
+ recentP99Ms: LATENCY_MIN_RECENT_P99_MS,
120
+ priorP99Ms: LATENCY_MIN_RECENT_P99_MS / 2,
121
+ priorSampleCount: LATENCY_MIN_PRIOR_SAMPLE_COUNT,
122
+ });
123
+ expect(decision.isRegression).toBe(true);
124
+ expect(decision.multiplier).toBe(2);
125
+ expect(decision.severity).toBe(AIInsightSeverity.Medium);
126
+ });
127
+
128
+ test("recent p99 just below the absolute floor never regresses", () => {
129
+ const decision: LatencyRegressionDecision =
130
+ TraceLatencyRegressionDetector.evaluateRegression({
131
+ recentP99Ms: LATENCY_MIN_RECENT_P99_MS - 1,
132
+ priorP99Ms: 100,
133
+ priorSampleCount: 10_000,
134
+ });
135
+ expect(decision.isRegression).toBe(false);
136
+ });
137
+
138
+ test("multiplier just below 2x does not regress", () => {
139
+ const decision: LatencyRegressionDecision =
140
+ TraceLatencyRegressionDetector.evaluateRegression({
141
+ recentP99Ms: 1000,
142
+ priorP99Ms: 501,
143
+ priorSampleCount: 1000,
144
+ });
145
+ expect(decision.isRegression).toBe(false);
146
+ });
147
+
148
+ test("thin prior sample count (one below the gate) does not regress", () => {
149
+ const decision: LatencyRegressionDecision =
150
+ TraceLatencyRegressionDetector.evaluateRegression({
151
+ recentP99Ms: 5000,
152
+ priorP99Ms: 500,
153
+ priorSampleCount: LATENCY_MIN_PRIOR_SAMPLE_COUNT - 1,
154
+ });
155
+ expect(decision.isRegression).toBe(false);
156
+ });
157
+
158
+ test("zero prior p99 (no baseline) never regresses and yields multiplier 0", () => {
159
+ const decision: LatencyRegressionDecision =
160
+ TraceLatencyRegressionDetector.evaluateRegression({
161
+ recentP99Ms: 5000,
162
+ priorP99Ms: 0,
163
+ priorSampleCount: 1000,
164
+ });
165
+ expect(decision.isRegression).toBe(false);
166
+ expect(decision.multiplier).toBe(0);
167
+ });
168
+
169
+ test("severity boundary: exactly 4x is High, just under stays Medium", () => {
170
+ const high: LatencyRegressionDecision =
171
+ TraceLatencyRegressionDetector.evaluateRegression({
172
+ recentP99Ms: 4000,
173
+ priorP99Ms: 1000,
174
+ priorSampleCount: 1000,
175
+ });
176
+ expect(high.multiplier).toBe(LATENCY_HIGH_SEVERITY_MULTIPLIER);
177
+ expect(high.severity).toBe(AIInsightSeverity.High);
178
+
179
+ const medium: LatencyRegressionDecision =
180
+ TraceLatencyRegressionDetector.evaluateRegression({
181
+ recentP99Ms: 3999,
182
+ priorP99Ms: 1000,
183
+ priorSampleCount: 1000,
184
+ });
185
+ expect(medium.isRegression).toBe(true);
186
+ expect(medium.severity).toBe(AIInsightSeverity.Medium);
187
+ });
188
+ });
189
+
190
+ describe("TraceLatencyRegressionDetector.joinServiceWindows (pure)", () => {
191
+ test("joins recent and prior rows on primaryEntityId", () => {
192
+ const joined: Array<ServiceLatencyWindows> =
193
+ TraceLatencyRegressionDetector.joinServiceWindows(
194
+ [profileRow({ entityId: "e1", count: 500, p99Ms: 2300 })],
195
+ [profileRow({ entityId: "e1", count: 400, p99Ms: 1000 })],
196
+ );
197
+ expect(joined).toEqual([
198
+ {
199
+ primaryEntityId: "e1",
200
+ recentP99Ms: 2300,
201
+ recentSampleCount: 500,
202
+ priorP99Ms: 1000,
203
+ priorSampleCount: 400,
204
+ },
205
+ ]);
206
+ });
207
+
208
+ test("a service missing from the prior window joins with a zero baseline", () => {
209
+ const joined: Array<ServiceLatencyWindows> =
210
+ TraceLatencyRegressionDetector.joinServiceWindows(
211
+ [profileRow({ entityId: "e1", count: 500, p99Ms: 2300 })],
212
+ [],
213
+ );
214
+ expect(joined[0]!.priorP99Ms).toBe(0);
215
+ expect(joined[0]!.priorSampleCount).toBe(0);
216
+ });
217
+
218
+ test("rows without an entity id are dropped from both sides", () => {
219
+ const joined: Array<ServiceLatencyWindows> =
220
+ TraceLatencyRegressionDetector.joinServiceWindows(
221
+ [profileRow({ entityId: "", count: 500, p99Ms: 2300 })],
222
+ [profileRow({ entityId: "", count: 400, p99Ms: 1000 })],
223
+ );
224
+ expect(joined).toEqual([]);
225
+ });
226
+ });
227
+
228
+ /*
229
+ * The operation name goes into the fingerprint, so this picker IS the
230
+ * dedupe key. A rule that lets a one-off slow span win produces a new
231
+ * fingerprint — and therefore a new insight row and a new triage LLM run —
232
+ * every 15 minutes for a single ongoing regression.
233
+ */
234
+ describe("TraceLatencyRegressionDetector.pickSlowestOperation (pure decision matrix)", () => {
235
+ test("a freak-slow op with no traffic loses to the slowest op that has traffic", () => {
236
+ expect(
237
+ TraceLatencyRegressionDetector.pickSlowestOperation([
238
+ topItem({ value: "POST /admin/export", p99Ms: 8000, count: 1 }),
239
+ topItem({ value: "GET /orders", p99Ms: 1200, count: 10_000 }),
240
+ ]),
241
+ ).toBe("GET /orders");
242
+ });
243
+
244
+ test("floor boundary: exactly at the constant qualifies, one below does not", () => {
245
+ expect(
246
+ TraceLatencyRegressionDetector.pickSlowestOperation([
247
+ topItem({
248
+ value: "at-floor",
249
+ p99Ms: 5000,
250
+ count: LATENCY_MIN_OPERATION_SAMPLE_COUNT,
251
+ }),
252
+ topItem({ value: "busy", p99Ms: 1200, count: 10_000 }),
253
+ ]),
254
+ ).toBe("at-floor");
255
+
256
+ expect(
257
+ TraceLatencyRegressionDetector.pickSlowestOperation([
258
+ topItem({
259
+ value: "below-floor",
260
+ p99Ms: 5000,
261
+ count: LATENCY_MIN_OPERATION_SAMPLE_COUNT - 1,
262
+ }),
263
+ topItem({ value: "busy", p99Ms: 1200, count: 10_000 }),
264
+ ]),
265
+ ).toBe("busy");
266
+ });
267
+
268
+ test("every candidate below the floor → undefined (service-level fallback)", () => {
269
+ expect(
270
+ TraceLatencyRegressionDetector.pickSlowestOperation([
271
+ topItem({ value: "rare-a", p99Ms: 9000, count: 1 }),
272
+ topItem({ value: "rare-b", p99Ms: 8000, count: 3 }),
273
+ ]),
274
+ ).toBeUndefined();
275
+ expect(
276
+ TraceLatencyRegressionDetector.pickSlowestOperation([]),
277
+ ).toBeUndefined();
278
+ });
279
+
280
+ test("empty dimension values never win, whatever their p99", () => {
281
+ expect(
282
+ TraceLatencyRegressionDetector.pickSlowestOperation([
283
+ topItem({ value: "", p99Ms: 9000, count: 10_000 }),
284
+ topItem({ value: "GET /orders", p99Ms: 1200, count: 10_000 }),
285
+ ]),
286
+ ).toBe("GET /orders");
287
+ });
288
+
289
+ test("tie-break is deterministic and independent of the row order the query returned", () => {
290
+ const items: Array<TraceAnalyticsTopItem> = [
291
+ topItem({ value: "b-op", p99Ms: 3000, count: 50 }),
292
+ topItem({ value: "a-op", p99Ms: 3000, count: 50 }),
293
+ // Same p99, more traffic — volume breaks the tie before the name does.
294
+ topItem({ value: "z-op", p99Ms: 3000, count: 900 }),
295
+ ];
296
+
297
+ expect(TraceLatencyRegressionDetector.pickSlowestOperation(items)).toBe(
298
+ "z-op",
299
+ );
300
+ expect(
301
+ TraceLatencyRegressionDetector.pickSlowestOperation([...items].reverse()),
302
+ ).toBe("z-op");
303
+
304
+ // p99 AND volume tied: the name is the last, total tie-break.
305
+ const namesOnly: Array<TraceAnalyticsTopItem> = [
306
+ topItem({ value: "b-op", p99Ms: 3000, count: 50 }),
307
+ topItem({ value: "a-op", p99Ms: 3000, count: 50 }),
308
+ ];
309
+ expect(TraceLatencyRegressionDetector.pickSlowestOperation(namesOnly)).toBe(
310
+ "a-op",
311
+ );
312
+ expect(
313
+ TraceLatencyRegressionDetector.pickSlowestOperation(
314
+ [...namesOnly].reverse(),
315
+ ),
316
+ ).toBe("a-op");
317
+ });
318
+
319
+ test("the picker does not mutate the caller's array", () => {
320
+ const items: Array<TraceAnalyticsTopItem> = [
321
+ topItem({ value: "slow", p99Ms: 9000, count: 1 }),
322
+ topItem({ value: "busy", p99Ms: 1200, count: 10_000 }),
323
+ ];
324
+ TraceLatencyRegressionDetector.pickSlowestOperation(items);
325
+ expect(items[0]!.value).toBe("slow");
326
+ });
327
+
328
+ /*
329
+ * Fingerprint stability across ticks: the rare ops churn from scan to
330
+ * scan while the regressing endpoint stays put. The fingerprint must not
331
+ * move with them, or the operator's dismissal (keyed on fingerprint)
332
+ * never suppresses anything.
333
+ */
334
+ test("fingerprint is stable across ticks as the rare-op set churns", () => {
335
+ const tickOne: Array<TraceAnalyticsTopItem> = [
336
+ topItem({ value: "POST /admin/export", p99Ms: 8000, count: 1 }),
337
+ topItem({ value: "GET /orders/42", p99Ms: 1200, count: 10_000 }),
338
+ ];
339
+ const tickTwo: Array<TraceAnalyticsTopItem> = [
340
+ topItem({ value: "GET /debug/dump", p99Ms: 7000, count: 2 }),
341
+ topItem({ value: "GET /orders/97", p99Ms: 1300, count: 9_000 }),
342
+ ];
343
+
344
+ const fingerprintOne: string =
345
+ TraceLatencyRegressionDetector.buildFingerprint(
346
+ "svc",
347
+ TraceLatencyRegressionDetector.pickSlowestOperation(tickOne),
348
+ );
349
+ const fingerprintTwo: string =
350
+ TraceLatencyRegressionDetector.buildFingerprint(
351
+ "svc",
352
+ TraceLatencyRegressionDetector.pickSlowestOperation(tickTwo),
353
+ );
354
+
355
+ expect(fingerprintOne).toBe("latency:svc:GET /orders/{n}");
356
+ expect(fingerprintTwo).toBe(fingerprintOne);
357
+ });
358
+ });
359
+
360
+ describe("TraceLatencyRegressionDetector.toAnalyzableSpans (pure ns→ms)", () => {
361
+ test("converts nanosecond timestamps and durations to milliseconds", () => {
362
+ const converted: Array<AnalyzableSpan> =
363
+ TraceLatencyRegressionDetector.toAnalyzableSpans([
364
+ {
365
+ spanId: "s1",
366
+ parentSpanId: "p1",
367
+ name: "op",
368
+ startTimeUnixNano: 1_500_000,
369
+ endTimeUnixNano: 4_500_000,
370
+ durationUnixNano: 3_000_000,
371
+ attributes: { "db.system": "postgres", numeric: 7 },
372
+ },
373
+ ] as unknown as Array<Span>);
374
+
375
+ expect(converted).toEqual([
376
+ {
377
+ spanId: "s1",
378
+ parentSpanId: "p1",
379
+ name: "op",
380
+ startMs: 1.5,
381
+ endMs: 4.5,
382
+ durationMs: 3,
383
+ attributes: { "db.system": "postgres", numeric: "7" },
384
+ },
385
+ ]);
386
+ });
387
+
388
+ test("missing parent and empty attributes stay well-formed", () => {
389
+ const converted: Array<AnalyzableSpan> =
390
+ TraceLatencyRegressionDetector.toAnalyzableSpans([
391
+ {
392
+ spanId: "s1",
393
+ name: "op",
394
+ startTimeUnixNano: 0,
395
+ endTimeUnixNano: 1_000_000,
396
+ durationUnixNano: 1_000_000,
397
+ },
398
+ ] as unknown as Array<Span>);
399
+ expect(converted[0]!.parentSpanId).toBeUndefined();
400
+ expect(converted[0]!.attributes).toEqual({});
401
+ });
402
+ });
403
+
404
+ describe("TraceLatencyRegressionDetector.buildFingerprint (pure)", () => {
405
+ test("normalizes ids/digits in the operation name for a stable key", () => {
406
+ expect(
407
+ TraceLatencyRegressionDetector.buildFingerprint("svc", "GET /users/42"),
408
+ ).toBe("latency:svc:GET /users/{n}");
409
+ expect(
410
+ TraceLatencyRegressionDetector.buildFingerprint("svc", "GET /users/97"),
411
+ ).toBe("latency:svc:GET /users/{n}");
412
+ });
413
+
414
+ test("missing operation yields a stable service-scoped key", () => {
415
+ expect(
416
+ TraceLatencyRegressionDetector.buildFingerprint("svc", undefined),
417
+ ).toBe("latency:svc:");
418
+ });
419
+ });
420
+
421
+ describe("TraceLatencyRegressionDetector.detect (IO wiring)", () => {
422
+ afterEach(() => {
423
+ jest.restoreAllMocks();
424
+ });
425
+
426
+ test("regression → drill to slowest op, representative trace, findings and code locations", async () => {
427
+ const profileSpy: jest.SpyInstance = jest
428
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
429
+ .mockResolvedValueOnce(
430
+ profile([profileRow({ entityId, count: 500, p99Ms: 2300 })]),
431
+ )
432
+ .mockResolvedValueOnce(
433
+ profile([profileRow({ entityId, count: 400, p99Ms: 1000 })]),
434
+ );
435
+ const topListSpy: jest.SpyInstance = jest
436
+ .spyOn(TraceAggregationService, "getAnalyticsTopList")
437
+ .mockResolvedValue([
438
+ { value: "GET /users/42", metricValue: 2300, count: 40 },
439
+ ]);
440
+ const findBySpy: jest.SpyInstance = jest
441
+ .spyOn(SpanService, "findBy")
442
+ .mockResolvedValueOnce([{ traceId: "trace-1" } as unknown as Span])
443
+ .mockResolvedValueOnce(fakeTraceSpans());
444
+ jest
445
+ .spyOn(ServiceService, "findOneById")
446
+ .mockResolvedValue({ name: "checkout" } as unknown as Service);
447
+
448
+ const detector: TraceLatencyRegressionDetector =
449
+ new TraceLatencyRegressionDetector();
450
+ const candidates: Array<InsightCandidate> = await detector.detect({
451
+ projectId,
452
+ now,
453
+ });
454
+
455
+ /*
456
+ * Stage 1: recent-hour and prior-24h per-service latency profiles, via
457
+ * the projection-served method — NOT getAnalyticsTable, whose stat set
458
+ * and raw-startTime predicate force a 25h full span scan per tick.
459
+ */
460
+ expect(profileSpy).toHaveBeenCalledTimes(2);
461
+ expect(profileSpy).toHaveBeenNthCalledWith(1, {
462
+ projectId: projectId,
463
+ startTime: oneHourAgo,
464
+ endTime: now,
465
+ limit: LATENCY_SERVICE_LIMIT,
466
+ });
467
+ expect(profileSpy).toHaveBeenNthCalledWith(2, {
468
+ projectId: projectId,
469
+ startTime: twentyFiveHoursAgo,
470
+ endTime: oneHourAgo,
471
+ limit: LATENCY_SERVICE_LIMIT,
472
+ });
473
+
474
+ // Drill 1: candidate operations ranked by p99, pinned to the service.
475
+ expect(topListSpy).toHaveBeenCalledTimes(1);
476
+ const topListRequest: Record<string, unknown> = topListSpy.mock
477
+ .calls[0]![0] as unknown as Record<string, unknown>;
478
+ expect(topListRequest["groupBy"]).toEqual(["name"]);
479
+ expect(topListRequest["metric"]).toBe("p99Duration");
480
+ expect(topListRequest["limit"]).toBe(LATENCY_TOP_OPERATION_CANDIDATES);
481
+ expect(
482
+ (topListRequest["serviceIds"] as Array<ObjectID>)[0]!.toString(),
483
+ ).toBe(entityId);
484
+
485
+ // Drill 2: slowest span of that op in the spike window, root query.
486
+ expect(findBySpy).toHaveBeenCalledTimes(2);
487
+ const slowestSpanFind: Record<string, unknown> = findBySpy.mock
488
+ .calls[0]![0] as unknown as Record<string, unknown>;
489
+ const slowestSpanQuery: Record<string, unknown> = slowestSpanFind[
490
+ "query"
491
+ ] as Record<string, unknown>;
492
+ expect(slowestSpanQuery["projectId"]).toBe(projectId);
493
+ expect(slowestSpanQuery["name"]).toBe("GET /users/42");
494
+ expect((slowestSpanQuery["primaryEntityId"] as ObjectID).toString()).toBe(
495
+ entityId,
496
+ );
497
+ const spanWindow: InBetween<Date> = slowestSpanQuery[
498
+ "startTime"
499
+ ] as InBetween<Date>;
500
+ expect(spanWindow).toBeInstanceOf(InBetween);
501
+ expect(spanWindow.startValue).toEqual(oneHourAgo);
502
+ expect(spanWindow.endValue).toEqual(now);
503
+ expect(slowestSpanFind["limit"]).toBe(1);
504
+ expect(slowestSpanFind["sort"]).toEqual({
505
+ durationUnixNano: SortOrder.Descending,
506
+ });
507
+ expect(slowestSpanFind["props"]).toEqual(
508
+ expect.objectContaining({ isRoot: true }),
509
+ );
510
+
511
+ // Drill 3: the whole trace, explicitly project-scoped, capped spans.
512
+ const traceFind: Record<string, unknown> = findBySpy.mock
513
+ .calls[1]![0] as unknown as Record<string, unknown>;
514
+ expect(traceFind["query"]).toEqual(
515
+ expect.objectContaining({ projectId: projectId, traceId: "trace-1" }),
516
+ );
517
+ expect(traceFind["limit"]).toBe(LATENCY_MAX_TRACE_SPANS);
518
+ expect(traceFind["props"]).toEqual(
519
+ expect.objectContaining({ isRoot: true }),
520
+ );
521
+
522
+ // The candidate carries the full drilled evidence.
523
+ expect(candidates).toHaveLength(1);
524
+ const candidate: InsightCandidate = candidates[0]!;
525
+ expect(candidate.insightType).toBe(AIInsightType.TraceLatencyRegression);
526
+ expect(candidate.fingerprint).toBe(`latency:${entityId}:GET /users/{n}`);
527
+ expect(candidate.title).toBe(
528
+ "Latency regression: p99 2.3x on GET /users/42 in checkout",
529
+ );
530
+ expect(candidate.severity).toBe(AIInsightSeverity.Medium);
531
+ expect(candidate.serviceName).toBe("checkout");
532
+ expect(candidate.telemetryServiceId?.toString()).toBe(entityId);
533
+ expect(candidate.traceId).toBe("trace-1");
534
+ expect(candidate.evidence.latency).toEqual(
535
+ expect.objectContaining({
536
+ recentP99Ms: 2300,
537
+ baselineP99Ms: 1000,
538
+ regressionMultiplier: 2.3,
539
+ operationName: "GET /users/42",
540
+ sampleTraceId: "trace-1",
541
+ }),
542
+ );
543
+ expect(
544
+ candidate.evidence.latency!.performanceFindings!.length,
545
+ ).toBeGreaterThan(0);
546
+ expect(candidate.evidence.latency!.codeLocations).toEqual([
547
+ { filePath: "src/db.ts", functionName: "loadUsers", lineNumber: 42 },
548
+ ]);
549
+ expect(candidate.detailMarkdown).toContain("Span-tree findings");
550
+ expect(candidate.detailMarkdown).toContain("Regression multiplier: 2.3x");
551
+ });
552
+
553
+ test("no regression → no drill queries at all", async () => {
554
+ jest
555
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
556
+ .mockResolvedValueOnce(
557
+ profile([profileRow({ entityId, count: 500, p99Ms: 1200 })]),
558
+ )
559
+ .mockResolvedValueOnce(
560
+ profile([profileRow({ entityId, count: 400, p99Ms: 900 })]),
561
+ );
562
+ const topListSpy: jest.SpyInstance = jest.spyOn(
563
+ TraceAggregationService,
564
+ "getAnalyticsTopList",
565
+ );
566
+ const findBySpy: jest.SpyInstance = jest.spyOn(SpanService, "findBy");
567
+
568
+ const detector: TraceLatencyRegressionDetector =
569
+ new TraceLatencyRegressionDetector();
570
+ const candidates: Array<InsightCandidate> = await detector.detect({
571
+ projectId,
572
+ now,
573
+ });
574
+
575
+ expect(candidates).toEqual([]);
576
+ expect(topListSpy).not.toHaveBeenCalled();
577
+ expect(findBySpy).not.toHaveBeenCalled();
578
+ });
579
+
580
+ test("regression with no drillable operation still produces evidence-bearing insight", async () => {
581
+ jest
582
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
583
+ .mockResolvedValueOnce(
584
+ profile([profileRow({ entityId, count: 500, p99Ms: 5000 })]),
585
+ )
586
+ .mockResolvedValueOnce(
587
+ profile([profileRow({ entityId, count: 400, p99Ms: 1000 })]),
588
+ );
589
+ jest
590
+ .spyOn(TraceAggregationService, "getAnalyticsTopList")
591
+ .mockResolvedValue([]);
592
+ const findBySpy: jest.SpyInstance = jest.spyOn(SpanService, "findBy");
593
+ jest.spyOn(ServiceService, "findOneById").mockResolvedValue(null);
594
+
595
+ const detector: TraceLatencyRegressionDetector =
596
+ new TraceLatencyRegressionDetector();
597
+ const candidates: Array<InsightCandidate> = await detector.detect({
598
+ projectId,
599
+ now,
600
+ });
601
+
602
+ expect(findBySpy).not.toHaveBeenCalled();
603
+ expect(candidates).toHaveLength(1);
604
+ expect(candidates[0]!.fingerprint).toBe(`latency:${entityId}:`);
605
+ expect(candidates[0]!.severity).toBe(AIInsightSeverity.High);
606
+ expect(candidates[0]!.traceId).toBeUndefined();
607
+ expect(
608
+ candidates[0]!.evidence.latency!.performanceFindings,
609
+ ).toBeUndefined();
610
+ });
611
+
612
+ /*
613
+ * The regression is real, but every operation in the spike hour is a
614
+ * one-off. Naming one of them would be a guess AND would move the dedupe
615
+ * key next tick — so the insight stays at service level: no drill
616
+ * queries, no operation in the title, stable service-scoped fingerprint.
617
+ */
618
+ test("no operation clears the sample floor → service-level insight, no drill, stable fingerprint", async () => {
619
+ jest
620
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
621
+ .mockResolvedValueOnce(
622
+ profile([profileRow({ entityId, count: 500, p99Ms: 5000 })]),
623
+ )
624
+ .mockResolvedValueOnce(
625
+ profile([profileRow({ entityId, count: 400, p99Ms: 1000 })]),
626
+ );
627
+ jest
628
+ .spyOn(TraceAggregationService, "getAnalyticsTopList")
629
+ .mockResolvedValue([
630
+ topItem({ value: "POST /admin/export", p99Ms: 9000, count: 1 }),
631
+ topItem({
632
+ value: "GET /rare",
633
+ p99Ms: 8000,
634
+ count: LATENCY_MIN_OPERATION_SAMPLE_COUNT - 1,
635
+ }),
636
+ ]);
637
+ const findBySpy: jest.SpyInstance = jest.spyOn(SpanService, "findBy");
638
+ jest
639
+ .spyOn(ServiceService, "findOneById")
640
+ .mockResolvedValue({ name: "checkout" } as unknown as Service);
641
+
642
+ const detector: TraceLatencyRegressionDetector =
643
+ new TraceLatencyRegressionDetector();
644
+ const candidates: Array<InsightCandidate> = await detector.detect({
645
+ projectId,
646
+ now,
647
+ });
648
+
649
+ expect(findBySpy).not.toHaveBeenCalled();
650
+ expect(candidates).toHaveLength(1);
651
+ expect(candidates[0]!.fingerprint).toBe(`latency:${entityId}:`);
652
+ expect(candidates[0]!.title).toBe(
653
+ "Latency regression: p99 5.0x in checkout",
654
+ );
655
+ expect(candidates[0]!.evidence.latency!.operationName).toBeUndefined();
656
+ expect(candidates[0]!.detailMarkdown).not.toContain("Slowest operation");
657
+ });
658
+
659
+ /*
660
+ * The drill must follow the CREDIBLE operation, not the freak one — the
661
+ * representative trace, the code locations and the fingerprint all hang
662
+ * off this choice.
663
+ */
664
+ test("a one-off slow op does not win the drill over the operation with real traffic", async () => {
665
+ jest
666
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
667
+ .mockResolvedValueOnce(
668
+ profile([profileRow({ entityId, count: 500, p99Ms: 2300 })]),
669
+ )
670
+ .mockResolvedValueOnce(
671
+ profile([profileRow({ entityId, count: 400, p99Ms: 1000 })]),
672
+ );
673
+ jest
674
+ .spyOn(TraceAggregationService, "getAnalyticsTopList")
675
+ .mockResolvedValue([
676
+ topItem({ value: "POST /admin/export", p99Ms: 9000, count: 1 }),
677
+ topItem({ value: "GET /users/42", p99Ms: 2300, count: 10_000 }),
678
+ ]);
679
+ const findBySpy: jest.SpyInstance = jest
680
+ .spyOn(SpanService, "findBy")
681
+ .mockResolvedValueOnce([{ traceId: "trace-1" } as unknown as Span])
682
+ .mockResolvedValueOnce(fakeTraceSpans());
683
+ jest
684
+ .spyOn(ServiceService, "findOneById")
685
+ .mockResolvedValue({ name: "checkout" } as unknown as Service);
686
+
687
+ const detector: TraceLatencyRegressionDetector =
688
+ new TraceLatencyRegressionDetector();
689
+ const candidates: Array<InsightCandidate> = await detector.detect({
690
+ projectId,
691
+ now,
692
+ });
693
+
694
+ const slowestSpanQuery: Record<string, unknown> = (
695
+ findBySpy.mock.calls[0]![0] as unknown as Record<string, unknown>
696
+ )["query"] as Record<string, unknown>;
697
+ expect(slowestSpanQuery["name"]).toBe("GET /users/42");
698
+ expect(candidates[0]!.fingerprint).toBe(
699
+ `latency:${entityId}:GET /users/{n}`,
700
+ );
701
+ expect(candidates[0]!.evidence.latency!.operationName).toBe(
702
+ "GET /users/42",
703
+ );
704
+ });
705
+
706
+ /*
707
+ * timeout_overflow_mode='break' returns partial aggregates with no
708
+ * error. A p99 over a fraction of the window compared against a whole
709
+ * one fabricates regressions — so a possibly-partial profile files
710
+ * NOTHING and waits for the next tick. Asserted on BOTH windows: the
711
+ * prior one is where a truncated scan does its worst damage.
712
+ */
713
+ test("a possibly-partial recent profile files nothing and never drills", async () => {
714
+ jest
715
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
716
+ .mockResolvedValueOnce({
717
+ rows: [profileRow({ entityId, count: 500, p99Ms: 5000 })],
718
+ isPartial: true,
719
+ })
720
+ .mockResolvedValueOnce(
721
+ profile([profileRow({ entityId, count: 400, p99Ms: 1000 })]),
722
+ );
723
+ const topListSpy: jest.SpyInstance = jest.spyOn(
724
+ TraceAggregationService,
725
+ "getAnalyticsTopList",
726
+ );
727
+ const findBySpy: jest.SpyInstance = jest.spyOn(SpanService, "findBy");
728
+
729
+ const detector: TraceLatencyRegressionDetector =
730
+ new TraceLatencyRegressionDetector();
731
+
732
+ await expect(detector.detect({ projectId, now })).resolves.toEqual([]);
733
+ expect(topListSpy).not.toHaveBeenCalled();
734
+ expect(findBySpy).not.toHaveBeenCalled();
735
+ });
736
+
737
+ test("a possibly-partial prior (baseline) profile files nothing", async () => {
738
+ jest
739
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
740
+ .mockResolvedValueOnce(
741
+ profile([profileRow({ entityId, count: 500, p99Ms: 5000 })]),
742
+ )
743
+ .mockResolvedValueOnce({
744
+ rows: [profileRow({ entityId, count: 400, p99Ms: 1000 })],
745
+ isPartial: true,
746
+ });
747
+ const topListSpy: jest.SpyInstance = jest.spyOn(
748
+ TraceAggregationService,
749
+ "getAnalyticsTopList",
750
+ );
751
+
752
+ const detector: TraceLatencyRegressionDetector =
753
+ new TraceLatencyRegressionDetector();
754
+
755
+ await expect(detector.detect({ projectId, now })).resolves.toEqual([]);
756
+ expect(topListSpy).not.toHaveBeenCalled();
757
+ });
758
+
759
+ test("detect propagates aggregation errors — the scanner isolates detectors", async () => {
760
+ jest
761
+ .spyOn(TraceAggregationService, "getServiceLatencyProfile")
762
+ .mockRejectedValue(new Error("clickhouse down"));
763
+
764
+ const detector: TraceLatencyRegressionDetector =
765
+ new TraceLatencyRegressionDetector();
766
+ await expect(detector.detect({ projectId, now })).rejects.toThrow(
767
+ "clickhouse down",
768
+ );
769
+ });
770
+ });