@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,218 @@
1
+ import FixRunBudget, {
2
+ DEFAULT_DAILY_FIX_RUN_LIMIT,
3
+ FixRunBudgetDecision,
4
+ } from "../../../../Server/Utils/AI/CodeFix/FixRunBudget";
5
+ import ProjectService from "../../../../Server/Services/ProjectService";
6
+ import AIRunService from "../../../../Server/Services/AIRunService";
7
+ import Project from "../../../../Models/DatabaseModels/Project";
8
+ import AIRunType from "../../../../Types/AI/AIRunType";
9
+ import BadDataException from "../../../../Types/Exception/BadDataException";
10
+ import ObjectID from "../../../../Types/ObjectID";
11
+ import PositiveNumber from "../../../../Types/PositiveNumber";
12
+ import { describe, expect, test, afterEach } from "@jest/globals";
13
+
14
+ /*
15
+ * The per-project daily fix-run budget (G11 guardrail): every CodeFix
16
+ * AIRun counts against Project.aiDailyFixTaskLimit per UTC day. Unlike the
17
+ * token budget, an UNSET limit is NOT unlimited — fix runs open pull
18
+ * requests on customer repositories, so the default cap applies. 0 pauses
19
+ * fix tasks entirely (the same kill-switch semantics as the token budget).
20
+ */
21
+
22
+ const projectId: ObjectID = ObjectID.generate();
23
+
24
+ describe("FixRunBudget.evaluate (pure decision)", () => {
25
+ test("unset limit uses the default cap — under it is allowed", () => {
26
+ const decision: FixRunBudgetDecision = FixRunBudget.evaluate({
27
+ configuredLimit: null,
28
+ runsToday: DEFAULT_DAILY_FIX_RUN_LIMIT - 1,
29
+ });
30
+
31
+ expect(decision.allowed).toBe(true);
32
+ expect(decision.limit).toBe(DEFAULT_DAILY_FIX_RUN_LIMIT);
33
+ expect(decision.paused).toBe(false);
34
+ });
35
+
36
+ test("unset limit is NOT unlimited: at the default cap is rejected", () => {
37
+ const decision: FixRunBudgetDecision = FixRunBudget.evaluate({
38
+ configuredLimit: undefined,
39
+ runsToday: DEFAULT_DAILY_FIX_RUN_LIMIT,
40
+ });
41
+
42
+ expect(decision.allowed).toBe(false);
43
+ expect(decision.paused).toBe(false);
44
+ });
45
+
46
+ test("a custom limit overrides the default in both directions", () => {
47
+ expect(
48
+ FixRunBudget.evaluate({ configuredLimit: 2, runsToday: 1 }).allowed,
49
+ ).toBe(true);
50
+ expect(
51
+ FixRunBudget.evaluate({ configuredLimit: 2, runsToday: 2 }).allowed,
52
+ ).toBe(false);
53
+ // A limit above the default allows more than the default would.
54
+ expect(
55
+ FixRunBudget.evaluate({
56
+ configuredLimit: 100,
57
+ runsToday: DEFAULT_DAILY_FIX_RUN_LIMIT,
58
+ }).allowed,
59
+ ).toBe(true);
60
+ });
61
+
62
+ test("0 pauses fix tasks outright — even with zero runs today", () => {
63
+ const decision: FixRunBudgetDecision = FixRunBudget.evaluate({
64
+ configuredLimit: 0,
65
+ runsToday: 0,
66
+ });
67
+
68
+ expect(decision.allowed).toBe(false);
69
+ expect(decision.paused).toBe(true);
70
+ });
71
+
72
+ test("a negative limit reads as paused, never as unlimited", () => {
73
+ const decision: FixRunBudgetDecision = FixRunBudget.evaluate({
74
+ configuredLimit: -5,
75
+ runsToday: 0,
76
+ });
77
+
78
+ expect(decision.allowed).toBe(false);
79
+ expect(decision.paused).toBe(true);
80
+ });
81
+
82
+ test("over the limit is rejected and reports the counts", () => {
83
+ const decision: FixRunBudgetDecision = FixRunBudget.evaluate({
84
+ configuredLimit: 3,
85
+ runsToday: 7,
86
+ });
87
+
88
+ expect(decision.allowed).toBe(false);
89
+ expect(decision.runsToday).toBe(7);
90
+ expect(decision.limit).toBe(3);
91
+ });
92
+ });
93
+
94
+ describe("FixRunBudget.describeRejection", () => {
95
+ test("paused rejection names the setting and the 0 value", () => {
96
+ const message: string = FixRunBudget.describeRejection(
97
+ FixRunBudget.evaluate({ configuredLimit: 0, runsToday: 0 }),
98
+ );
99
+
100
+ expect(message).toMatch(/Daily AI Fix Task Limit/);
101
+ expect(message).toMatch(/0/);
102
+ });
103
+
104
+ test("over-budget rejection names the counts, the setting and the default", () => {
105
+ const message: string = FixRunBudget.describeRejection(
106
+ FixRunBudget.evaluate({ configuredLimit: 10, runsToday: 10 }),
107
+ );
108
+
109
+ expect(message).toMatch(/10 of 10/);
110
+ expect(message).toMatch(/Daily AI Fix Task Limit/);
111
+ expect(message).toMatch(new RegExp(String(DEFAULT_DAILY_FIX_RUN_LIMIT)));
112
+ });
113
+ });
114
+
115
+ describe("FixRunBudget.getBudgetStatus (IO wiring)", () => {
116
+ afterEach(() => {
117
+ jest.restoreAllMocks();
118
+ });
119
+
120
+ test("counts the project's CodeFix runs created since UTC midnight", async () => {
121
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue({
122
+ id: projectId,
123
+ aiDailyFixTaskLimit: 10,
124
+ } as unknown as Project);
125
+
126
+ const countBy: jest.SpyInstance = jest
127
+ .spyOn(AIRunService, "countBy")
128
+ .mockResolvedValue(new PositiveNumber(4));
129
+
130
+ const decision: FixRunBudgetDecision =
131
+ await FixRunBudget.getBudgetStatus(projectId);
132
+
133
+ expect(decision).toEqual({
134
+ allowed: true,
135
+ limit: 10,
136
+ paused: false,
137
+ runsToday: 4,
138
+ });
139
+
140
+ expect(countBy).toHaveBeenCalledWith(
141
+ expect.objectContaining({
142
+ query: expect.objectContaining({
143
+ projectId,
144
+ runType: AIRunType.CodeFix,
145
+ // createdAt >= UTC midnight rides in a QueryHelper find operator.
146
+ createdAt: expect.anything(),
147
+ }),
148
+ props: expect.objectContaining({ isRoot: true }),
149
+ }),
150
+ );
151
+ });
152
+
153
+ test("a paused project (limit 0) short-circuits without the count query", async () => {
154
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue({
155
+ id: projectId,
156
+ aiDailyFixTaskLimit: 0,
157
+ } as unknown as Project);
158
+
159
+ const countBy: jest.SpyInstance = jest.spyOn(AIRunService, "countBy");
160
+
161
+ const decision: FixRunBudgetDecision =
162
+ await FixRunBudget.getBudgetStatus(projectId);
163
+
164
+ expect(decision.allowed).toBe(false);
165
+ expect(decision.paused).toBe(true);
166
+ expect(countBy).not.toHaveBeenCalled();
167
+ });
168
+
169
+ test("a missing project row falls back to the default cap (fail-safe, not fail-open)", async () => {
170
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(null);
171
+ jest
172
+ .spyOn(AIRunService, "countBy")
173
+ .mockResolvedValue(new PositiveNumber(DEFAULT_DAILY_FIX_RUN_LIMIT));
174
+
175
+ const decision: FixRunBudgetDecision =
176
+ await FixRunBudget.getBudgetStatus(projectId);
177
+
178
+ expect(decision.limit).toBe(DEFAULT_DAILY_FIX_RUN_LIMIT);
179
+ expect(decision.allowed).toBe(false);
180
+ });
181
+ });
182
+
183
+ describe("FixRunBudget.assertWithinBudget", () => {
184
+ afterEach(() => {
185
+ jest.restoreAllMocks();
186
+ });
187
+
188
+ test("under budget resolves silently", async () => {
189
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue({
190
+ id: projectId,
191
+ aiDailyFixTaskLimit: 5,
192
+ } as unknown as Project);
193
+ jest
194
+ .spyOn(AIRunService, "countBy")
195
+ .mockResolvedValue(new PositiveNumber(1));
196
+
197
+ await expect(
198
+ FixRunBudget.assertWithinBudget(projectId),
199
+ ).resolves.toBeUndefined();
200
+ });
201
+
202
+ test("over budget throws a BadDataException naming the setting", async () => {
203
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue({
204
+ id: projectId,
205
+ aiDailyFixTaskLimit: 5,
206
+ } as unknown as Project);
207
+ jest
208
+ .spyOn(AIRunService, "countBy")
209
+ .mockResolvedValue(new PositiveNumber(5));
210
+
211
+ await expect(FixRunBudget.assertWithinBudget(projectId)).rejects.toThrow(
212
+ BadDataException,
213
+ );
214
+ await expect(FixRunBudget.assertWithinBudget(projectId)).rejects.toThrow(
215
+ /Daily AI Fix Task Limit/,
216
+ );
217
+ });
218
+ });
@@ -0,0 +1,437 @@
1
+ /** @timezone Asia/Kolkata */
2
+
3
+ import { afterEach, describe, expect, test } from "@jest/globals";
4
+ import ErrorLogSpikeDetector, {
5
+ ERROR_LOG_SEVERITIES,
6
+ ERROR_LOG_SPIKE_HIGH_SEVERITY_MULTIPLIER,
7
+ ERROR_LOG_SPIKE_HISTOGRAM_BUCKET_MINUTES,
8
+ ERROR_LOG_SPIKE_MAX_ATTRIBUTED_SERVICES,
9
+ ERROR_LOG_SPIKE_MIN_MULTIPLIER,
10
+ ERROR_LOG_SPIKE_MIN_RECENT_COUNT,
11
+ ErrorLogSpikeDecision,
12
+ } from "../../../../../Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector";
13
+ import { InsightCandidate } from "../../../../../Server/Utils/AI/SRE/Insights/Types";
14
+ import LogAggregationService, {
15
+ HistogramBucket,
16
+ } from "../../../../../Server/Services/LogAggregationService";
17
+ import ServiceService from "../../../../../Server/Services/ServiceService";
18
+ import Service from "../../../../../Models/DatabaseModels/Service";
19
+ import AIInsightSeverity from "../../../../../Types/AI/AIInsightSeverity";
20
+ import AIInsightType from "../../../../../Types/AI/AIInsightType";
21
+ import ObjectID from "../../../../../Types/ObjectID";
22
+
23
+ /*
24
+ * Invariant under test: the ErrorLogSpike detector fires exactly when the
25
+ * project's Error/Fatal log count in the last hour is >= 100 AND >= 3x its
26
+ * average hourly rate over the prior 24h (baseline floored at 1/hour),
27
+ * escalating to High at 10x — stage 1 is ONE projection-shaped histogram
28
+ * (no service filter), and the scan-costly service attribution runs ONLY
29
+ * after a spike is found, bounded to the spike hour and capped at 3
30
+ * services. No LLM is ever involved.
31
+ *
32
+ * The suite is PINNED to a non-UTC process timezone (docblock pragma above,
33
+ * honored by Tests/Utils/TimezoneEnvironment.js). Asia/Kolkata is chosen for
34
+ * two properties: it is a POSITIVE offset, the direction that silently
35
+ * SUPPRESSES spikes (bad buckets fall out of the recent window and inflate
36
+ * the baseline they are compared against — a detector that reports nothing
37
+ * looks healthy), and it is a :30 offset, which a whole-hours-only fix would
38
+ * still get wrong. Every bucket fixture below therefore uses the shape
39
+ * ClickHouse actually emits — a zone-LESS "YYYY-MM-DD hh:mm:ss" wall clock —
40
+ * and every expectation is an absolute UTC instant, so the suite holds only
41
+ * if bucket times are parsed as UTC rather than as the worker's local time.
42
+ */
43
+
44
+ const projectId: ObjectID = ObjectID.generate();
45
+ const now: Date = new Date("2026-07-14T12:00:00.000Z");
46
+ const serviceIdA: string = ObjectID.generate().toString();
47
+ const serviceIdB: string = ObjectID.generate().toString();
48
+
49
+ // The real ClickHouse DateTime rendering: no zone designator, space-separated.
50
+ function bucket(time: string, count: number): HistogramBucket {
51
+ return { time, severity: "Error", count };
52
+ }
53
+
54
+ describe("test environment (guards the fixtures below from being vacuous)", () => {
55
+ test("the process runs in a non-UTC zone that skews zone-less parsing", () => {
56
+ expect(process.env["TZ"]).toBe("Asia/Kolkata");
57
+
58
+ /*
59
+ * Proof that this suite is adversarial rather than accidentally green: a
60
+ * bare `new Date(clickhouseWallClock)` here does NOT land on the UTC
61
+ * instant of the same wall clock, it lands 5h30m earlier. Every zone-less
62
+ * fixture below is therefore a live trap for local-time parsing.
63
+ */
64
+ const naive: number = new Date("2026-07-14 11:05:00").getTime();
65
+ expect(naive).toBe(Date.UTC(2026, 6, 14, 11, 5, 0) - 5.5 * 60 * 60 * 1000);
66
+ });
67
+ });
68
+
69
+ describe("ErrorLogSpikeDetector.parseBucketTime (pure)", () => {
70
+ test("a zone-less ClickHouse wall clock is read as UTC, not as local time", () => {
71
+ expect(
72
+ ErrorLogSpikeDetector.parseBucketTime("2026-07-14 11:05:00").getTime(),
73
+ ).toBe(Date.UTC(2026, 6, 14, 11, 5, 0));
74
+ });
75
+
76
+ test("a zone-less T-separated clock is read as UTC too", () => {
77
+ expect(
78
+ ErrorLogSpikeDetector.parseBucketTime("2026-07-14T11:05:00").getTime(),
79
+ ).toBe(Date.UTC(2026, 6, 14, 11, 5, 0));
80
+ });
81
+
82
+ test("fractional seconds (DateTime64) survive the UTC normalization", () => {
83
+ expect(
84
+ ErrorLogSpikeDetector.parseBucketTime(
85
+ "2026-07-14 11:05:00.123",
86
+ ).getTime(),
87
+ ).toBe(Date.UTC(2026, 6, 14, 11, 5, 0) + 123);
88
+ });
89
+
90
+ test("an ISO-Z string passes through untouched (no double-Z Invalid Date)", () => {
91
+ const parsed: Date = ErrorLogSpikeDetector.parseBucketTime(
92
+ "2026-07-14T11:05:00.000Z",
93
+ );
94
+ expect(isNaN(parsed.getTime())).toBe(false);
95
+ expect(parsed.getTime()).toBe(Date.UTC(2026, 6, 14, 11, 5, 0));
96
+ });
97
+
98
+ test("an explicit +/- offset passes through and keeps its own zone", () => {
99
+ // 11:05 at +05:30 is 05:35 UTC — the offset must be honored, not appended to.
100
+ const positive: Date = ErrorLogSpikeDetector.parseBucketTime(
101
+ "2026-07-14 11:05:00+05:30",
102
+ );
103
+ expect(isNaN(positive.getTime())).toBe(false);
104
+ expect(positive.getTime()).toBe(Date.UTC(2026, 6, 14, 5, 35, 0));
105
+
106
+ // 11:05 at -08:00 is 19:05 UTC.
107
+ const negative: Date = ErrorLogSpikeDetector.parseBucketTime(
108
+ "2026-07-14T11:05:00-08:00",
109
+ );
110
+ expect(isNaN(negative.getTime())).toBe(false);
111
+ expect(negative.getTime()).toBe(Date.UTC(2026, 6, 14, 19, 5, 0));
112
+ });
113
+
114
+ test("garbage stays an Invalid Date so the caller's isNaN guard still skips it", () => {
115
+ expect(
116
+ isNaN(ErrorLogSpikeDetector.parseBucketTime("not-a-date").getTime()),
117
+ ).toBe(true);
118
+ expect(isNaN(ErrorLogSpikeDetector.parseBucketTime("").getTime())).toBe(
119
+ true,
120
+ );
121
+ });
122
+ });
123
+
124
+ describe("ErrorLogSpikeDetector.splitHistogram (pure)", () => {
125
+ const boundary: Date = new Date("2026-07-14T11:00:00.000Z");
126
+
127
+ test("buckets at or after the boundary are recent; earlier ones are prior", () => {
128
+ const split: { recentCount: number; priorCount: number } =
129
+ ErrorLogSpikeDetector.splitHistogram(
130
+ [
131
+ bucket("2026-07-14 10:55:00", 7),
132
+ bucket("2026-07-14 11:00:00", 11),
133
+ bucket("2026-07-14 11:30:00", 13),
134
+ bucket("2026-07-13 12:00:00", 5),
135
+ ],
136
+ boundary,
137
+ );
138
+ expect(split.recentCount).toBe(24);
139
+ expect(split.priorCount).toBe(12);
140
+ });
141
+
142
+ test("the zone-less ClickHouse shape splits identically to its ISO-Z equivalent", () => {
143
+ /*
144
+ * Regression lock for the local-time parsing bug: these two fixtures are
145
+ * the same four instants written two ways. Under the bug the zone-less
146
+ * form drifted by the worker's UTC offset (here it lost the entire recent
147
+ * window into the baseline) while the ISO-Z form did not — which is
148
+ * exactly why the original ISO-Z-only fixture could not see the defect.
149
+ */
150
+ const clickhouseSplit: { recentCount: number; priorCount: number } =
151
+ ErrorLogSpikeDetector.splitHistogram(
152
+ [
153
+ bucket("2026-07-14 11:05:00", 500),
154
+ bucket("2026-07-14 11:55:00", 250),
155
+ bucket("2026-07-14 10:59:00", 40),
156
+ bucket("2026-07-14 09:00:00", 200),
157
+ ],
158
+ boundary,
159
+ );
160
+ const isoSplit: { recentCount: number; priorCount: number } =
161
+ ErrorLogSpikeDetector.splitHistogram(
162
+ [
163
+ bucket("2026-07-14T11:05:00.000Z", 500),
164
+ bucket("2026-07-14T11:55:00.000Z", 250),
165
+ bucket("2026-07-14T10:59:00.000Z", 40),
166
+ bucket("2026-07-14T09:00:00.000Z", 200),
167
+ ],
168
+ boundary,
169
+ );
170
+
171
+ expect(clickhouseSplit).toEqual({ recentCount: 750, priorCount: 240 });
172
+ expect(clickhouseSplit).toEqual(isoSplit);
173
+ });
174
+
175
+ test("a bucket straddling the boundary counts as prior (conservative bias)", () => {
176
+ const split: { recentCount: number; priorCount: number } =
177
+ ErrorLogSpikeDetector.splitHistogram(
178
+ [bucket("2026-07-14 10:59:00", 100)],
179
+ boundary,
180
+ );
181
+ expect(split.recentCount).toBe(0);
182
+ expect(split.priorCount).toBe(100);
183
+ });
184
+
185
+ test("unparseable bucket times are skipped, empty input splits to zeros", () => {
186
+ const split: { recentCount: number; priorCount: number } =
187
+ ErrorLogSpikeDetector.splitHistogram(
188
+ [bucket("not-a-date", 999)],
189
+ boundary,
190
+ );
191
+ expect(split).toEqual({ recentCount: 0, priorCount: 0 });
192
+ expect(ErrorLogSpikeDetector.splitHistogram([], boundary)).toEqual({
193
+ recentCount: 0,
194
+ priorCount: 0,
195
+ });
196
+ });
197
+ });
198
+
199
+ describe("ErrorLogSpikeDetector.evaluateSpike (pure decision matrix)", () => {
200
+ test("exactly the recent floor on a zero baseline spikes at High", () => {
201
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
202
+ ERROR_LOG_SPIKE_MIN_RECENT_COUNT,
203
+ 0,
204
+ );
205
+ expect(decision.isSpike).toBe(true);
206
+ expect(decision.multiplier).toBe(ERROR_LOG_SPIKE_MIN_RECENT_COUNT);
207
+ expect(decision.severity).toBe(AIInsightSeverity.High);
208
+ });
209
+
210
+ test("one below the recent floor never spikes", () => {
211
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
212
+ ERROR_LOG_SPIKE_MIN_RECENT_COUNT - 1,
213
+ 0,
214
+ );
215
+ expect(decision.isSpike).toBe(false);
216
+ });
217
+
218
+ test("exactly the multiplier threshold spikes (300 vs 100/hour baseline)", () => {
219
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
220
+ 300,
221
+ 2400,
222
+ );
223
+ expect(decision.multiplier).toBe(ERROR_LOG_SPIKE_MIN_MULTIPLIER);
224
+ expect(decision.isSpike).toBe(true);
225
+ expect(decision.severity).toBe(AIInsightSeverity.Medium);
226
+ });
227
+
228
+ test("just under the multiplier threshold does not spike", () => {
229
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
230
+ 299,
231
+ 2400,
232
+ );
233
+ expect(decision.isSpike).toBe(false);
234
+ });
235
+
236
+ test("chronically chatty projects do not spike on their normal volume", () => {
237
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
238
+ 5000,
239
+ 5000 * 24,
240
+ );
241
+ expect(decision.isSpike).toBe(false);
242
+ expect(decision.multiplier).toBe(1);
243
+ });
244
+
245
+ test("severity boundary: exactly 10x is High", () => {
246
+ const decision: ErrorLogSpikeDecision = ErrorLogSpikeDetector.evaluateSpike(
247
+ 1000,
248
+ 2400,
249
+ );
250
+ expect(decision.multiplier).toBe(ERROR_LOG_SPIKE_HIGH_SEVERITY_MULTIPLIER);
251
+ expect(decision.severity).toBe(AIInsightSeverity.High);
252
+ });
253
+ });
254
+
255
+ describe("ErrorLogSpikeDetector.buildFingerprint (pure)", () => {
256
+ test("per-service and project-wide wire-contract formats", () => {
257
+ expect(ErrorLogSpikeDetector.buildFingerprint("svc1")).toBe(
258
+ "error-log-spike:svc1",
259
+ );
260
+ expect(ErrorLogSpikeDetector.buildFingerprint(undefined)).toBe(
261
+ "error-log-spike:project",
262
+ );
263
+ });
264
+ });
265
+
266
+ describe("ErrorLogSpikeDetector.detect (IO wiring)", () => {
267
+ afterEach(() => {
268
+ jest.restoreAllMocks();
269
+ });
270
+
271
+ test("spike → one insight per attributed service, sharing the project-wide evidence", async () => {
272
+ const getHistogramSpy: jest.SpyInstance = jest
273
+ .spyOn(LogAggregationService, "getHistogram")
274
+ .mockResolvedValue([
275
+ bucket("2026-07-14 11:05:00", 500),
276
+ bucket("2026-07-14 09:00:00", 240),
277
+ ]);
278
+ const topListSpy: jest.SpyInstance = jest
279
+ .spyOn(LogAggregationService, "getAnalyticsTopList")
280
+ .mockResolvedValue([
281
+ { value: serviceIdA, count: 300 },
282
+ { value: serviceIdB, count: 100 },
283
+ ]);
284
+ jest
285
+ .spyOn(ServiceService, "findOneById")
286
+ .mockResolvedValueOnce({ name: "api" } as unknown as Service)
287
+ .mockResolvedValueOnce(null);
288
+
289
+ const detector: ErrorLogSpikeDetector = new ErrorLogSpikeDetector();
290
+ const candidates: Array<InsightCandidate> = await detector.detect({
291
+ projectId,
292
+ now,
293
+ });
294
+
295
+ // Stage 1: one projection-shaped project-wide histogram over 25h.
296
+ expect(getHistogramSpy).toHaveBeenCalledWith(
297
+ expect.objectContaining({
298
+ projectId: projectId,
299
+ startTime: new Date("2026-07-13T11:00:00.000Z"),
300
+ endTime: now,
301
+ bucketSizeInMinutes: ERROR_LOG_SPIKE_HISTOGRAM_BUCKET_MINUTES,
302
+ severityTexts: ERROR_LOG_SEVERITIES,
303
+ }),
304
+ );
305
+ // No service filter on the projection path.
306
+ expect(
307
+ (getHistogramSpy.mock.calls[0]![0] as unknown as Record<string, unknown>)[
308
+ "serviceIds"
309
+ ],
310
+ ).toBeUndefined();
311
+
312
+ // Stage 2: attribution bounded to the spike hour, capped at 3.
313
+ expect(topListSpy).toHaveBeenCalledWith(
314
+ expect.objectContaining({
315
+ projectId: projectId,
316
+ startTime: new Date("2026-07-14T11:00:00.000Z"),
317
+ endTime: now,
318
+ groupBy: ["primaryEntityId"],
319
+ aggregation: "count",
320
+ severityTexts: ERROR_LOG_SEVERITIES,
321
+ limit: ERROR_LOG_SPIKE_MAX_ATTRIBUTED_SERVICES,
322
+ }),
323
+ );
324
+
325
+ /*
326
+ * 500 recent vs 10/hour baseline → 50x, High, two service insights. The
327
+ * stage-2 window above is bound as a real Date (true UTC hour), so under
328
+ * the local-time parsing bug a non-UTC worker would not merely miss the
329
+ * spike — its stage-1 counts would not even reconcile with the hour it
330
+ * attributes. This assertion holds only when both stages agree on UTC.
331
+ */
332
+ expect(candidates).toHaveLength(2);
333
+ const first: InsightCandidate = candidates[0]!;
334
+ expect(first.insightType).toBe(AIInsightType.ErrorLogSpike);
335
+ expect(first.fingerprint).toBe(`error-log-spike:${serviceIdA}`);
336
+ expect(first.title).toBe("Error-log spike: 50.0x normal volume in api");
337
+ expect(first.severity).toBe(AIInsightSeverity.High);
338
+ expect(first.serviceName).toBe("api");
339
+ expect(first.telemetryServiceId?.toString()).toBe(serviceIdA);
340
+ expect(first.evidence.logSpike).toEqual(
341
+ expect.objectContaining({
342
+ recentErrorCount: 500,
343
+ baselineHourlyAverage: 10,
344
+ spikeMultiplier: 50,
345
+ windowMinutes: 60,
346
+ }),
347
+ );
348
+ expect(first.evidence.logSpike!.topServices).toEqual([
349
+ { serviceName: "api", count: 300 },
350
+ { serviceName: serviceIdB, count: 100 },
351
+ ]);
352
+
353
+ // Unresolvable entity keeps its raw id and no telemetryServiceId.
354
+ const second: InsightCandidate = candidates[1]!;
355
+ expect(second.fingerprint).toBe(`error-log-spike:${serviceIdB}`);
356
+ expect(second.serviceName).toBe(serviceIdB);
357
+ expect(second.telemetryServiceId).toBeUndefined();
358
+ });
359
+
360
+ test("no spike → no insights and NO stage-2 attribution query", async () => {
361
+ jest
362
+ .spyOn(LogAggregationService, "getHistogram")
363
+ .mockResolvedValue([bucket("2026-07-14 11:05:00", 50)]);
364
+ const topListSpy: jest.SpyInstance = jest.spyOn(
365
+ LogAggregationService,
366
+ "getAnalyticsTopList",
367
+ );
368
+
369
+ const detector: ErrorLogSpikeDetector = new ErrorLogSpikeDetector();
370
+ const candidates: Array<InsightCandidate> = await detector.detect({
371
+ projectId,
372
+ now,
373
+ });
374
+
375
+ expect(candidates).toEqual([]);
376
+ expect(topListSpy).not.toHaveBeenCalled();
377
+ });
378
+
379
+ test("spike with empty attribution → single project-wide insight", async () => {
380
+ jest
381
+ .spyOn(LogAggregationService, "getHistogram")
382
+ .mockResolvedValue([bucket("2026-07-14 11:05:00", 500)]);
383
+ jest
384
+ .spyOn(LogAggregationService, "getAnalyticsTopList")
385
+ .mockResolvedValue([]);
386
+
387
+ const detector: ErrorLogSpikeDetector = new ErrorLogSpikeDetector();
388
+ const candidates: Array<InsightCandidate> = await detector.detect({
389
+ projectId,
390
+ now,
391
+ });
392
+
393
+ expect(candidates).toHaveLength(1);
394
+ expect(candidates[0]!.fingerprint).toBe("error-log-spike:project");
395
+ expect(candidates[0]!.title).toContain("across the project");
396
+ expect(candidates[0]!.serviceName).toBeUndefined();
397
+ expect(candidates[0]!.evidence.logSpike!.topServices).toEqual([]);
398
+ });
399
+
400
+ test("a zone-carrying histogram still spikes (no double-Z zeroing)", async () => {
401
+ /*
402
+ * Belt-and-braces on the passthrough branch: if a ClickHouse setting ever
403
+ * starts emitting a zone designator, the detector must keep counting those
404
+ * buckets rather than parsing them to Invalid Date and reporting silence.
405
+ */
406
+ jest
407
+ .spyOn(LogAggregationService, "getHistogram")
408
+ .mockResolvedValue([
409
+ bucket("2026-07-14T11:05:00.000Z", 500),
410
+ bucket("2026-07-14T09:00:00.000Z", 240),
411
+ ]);
412
+ jest
413
+ .spyOn(LogAggregationService, "getAnalyticsTopList")
414
+ .mockResolvedValue([]);
415
+
416
+ const detector: ErrorLogSpikeDetector = new ErrorLogSpikeDetector();
417
+ const candidates: Array<InsightCandidate> = await detector.detect({
418
+ projectId,
419
+ now,
420
+ });
421
+
422
+ expect(candidates).toHaveLength(1);
423
+ expect(candidates[0]!.evidence.logSpike!.recentErrorCount).toBe(500);
424
+ expect(candidates[0]!.evidence.logSpike!.spikeMultiplier).toBe(50);
425
+ });
426
+
427
+ test("detect propagates histogram errors — the scanner isolates detectors", async () => {
428
+ jest
429
+ .spyOn(LogAggregationService, "getHistogram")
430
+ .mockRejectedValue(new Error("clickhouse down"));
431
+
432
+ const detector: ErrorLogSpikeDetector = new ErrorLogSpikeDetector();
433
+ await expect(detector.detect({ projectId, now })).rejects.toThrow(
434
+ "clickhouse down",
435
+ );
436
+ });
437
+ });