@oneuptime/common 12.0.4 → 12.0.5

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 (374) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/Dashboard.ts +28 -0
  4. package/Models/DatabaseModels/Incident.ts +2 -0
  5. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  7. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  8. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  9. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  10. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  11. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  12. package/Models/DatabaseModels/Project.ts +231 -9
  13. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  14. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  15. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  17. package/Models/DatabaseModels/StatusPage.ts +28 -0
  18. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  19. package/Server/API/AIAgentDataAPI.ts +44 -55
  20. package/Server/API/AIInvestigationAPI.ts +175 -17
  21. package/Server/API/DashboardAPI.ts +10 -10
  22. package/Server/API/StatusPageAPI.ts +38 -19
  23. package/Server/EnvironmentConfig.ts +16 -0
  24. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  25. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Services/AIRunService.ts +78 -10
  33. package/Server/Services/AIService.ts +94 -22
  34. package/Server/Services/AlertFeedService.ts +5 -0
  35. package/Server/Services/AnalyticsDatabaseService.ts +29 -0
  36. package/Server/Services/DatabaseService.ts +43 -2
  37. package/Server/Services/IncidentFeedService.ts +5 -0
  38. package/Server/Services/LlmLogService.ts +46 -2
  39. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  40. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  41. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  42. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  43. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  44. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  45. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  46. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  47. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  48. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  49. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  50. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  51. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  52. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  53. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  54. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  55. package/Server/Utils/AI/SRE/README.md +1 -1
  56. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  57. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  58. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  59. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  60. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  61. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  62. package/Server/Utils/PasswordHash.ts +28 -4
  63. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  64. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  65. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  66. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  67. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  68. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  69. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  70. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  71. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  72. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  73. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  74. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  75. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  76. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  77. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  78. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  79. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  80. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  81. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +25 -1
  82. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +45 -35
  83. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  84. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  85. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  86. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  87. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  88. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  89. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  90. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  91. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  92. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  93. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  94. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  95. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  96. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  97. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  98. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  99. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  100. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  101. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  102. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  103. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  104. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  105. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  106. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  107. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  108. package/Tests/Server/Utils/PasswordHash.test.ts +30 -0
  109. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  110. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  111. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  112. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  113. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  114. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  115. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  116. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  117. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  118. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  119. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  120. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  121. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  122. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  123. package/Tests/Types/Permission.test.ts +137 -0
  124. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  125. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  126. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  127. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  128. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  129. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  130. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  131. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  132. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  133. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  134. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  135. package/Tests/UI/Utils/Project.test.ts +31 -0
  136. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  137. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  138. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  139. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  140. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  141. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  142. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  143. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  144. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  145. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  146. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  147. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  148. package/Types/AI/CodeFixTaskContext.ts +63 -3
  149. package/Types/AI/CodeFixTaskType.ts +3 -3
  150. package/Types/HashedString.ts +4 -3
  151. package/Types/Monitor/CriteriaFilter.ts +4 -0
  152. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  153. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  155. package/Types/Monitor/MonitorMetricType.ts +8 -0
  156. package/Types/Monitor/MonitorStep.ts +10 -1
  157. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  158. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  159. package/Types/Permission.ts +23 -175
  160. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  161. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  162. package/UI/Components/ErrorBoundary.tsx +138 -11
  163. package/UI/Components/Feed/FeedItem.tsx +9 -2
  164. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  165. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  166. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  167. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  168. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  169. package/UI/Utils/DownloadFile.ts +16 -8
  170. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  171. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  172. package/UI/Utils/Project.ts +4 -0
  173. package/UI/Utils/StatusPage.ts +8 -2
  174. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  175. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  176. package/Utils/Dashboard/GridLayout.ts +523 -0
  177. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  178. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  179. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  180. package/Utils/StatusPage/GroupTree.ts +157 -66
  181. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  182. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  183. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  184. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  185. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  187. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  189. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  191. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  193. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  195. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  197. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  199. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  201. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  203. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  205. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/Project.js +241 -11
  207. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  209. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  211. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  212. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  213. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  214. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  215. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  216. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  218. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  219. package/build/dist/Server/API/AIAgentDataAPI.js +28 -46
  220. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  221. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  222. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  223. package/build/dist/Server/API/DashboardAPI.js +8 -5
  224. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  225. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  226. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  227. package/build/dist/Server/EnvironmentConfig.js +14 -0
  228. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  229. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  230. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  231. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  232. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  245. package/build/dist/Server/Services/AIRunService.js +58 -12
  246. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  247. package/build/dist/Server/Services/AIService.js +74 -21
  248. package/build/dist/Server/Services/AIService.js.map +1 -1
  249. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  250. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  251. package/build/dist/Server/Services/AnalyticsDatabaseService.js +29 -1
  252. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  253. package/build/dist/Server/Services/DatabaseService.js +21 -2
  254. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  255. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  256. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  257. package/build/dist/Server/Services/LlmLogService.js +22 -1
  258. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  259. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  260. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  261. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  262. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  263. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  264. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  265. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  266. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  267. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  268. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  269. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  270. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  272. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  274. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  276. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  278. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  279. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  280. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  281. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  282. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  283. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  284. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  285. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  286. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  287. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  288. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  290. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  292. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  293. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  294. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  295. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  296. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  297. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  298. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  299. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  300. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  301. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  302. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  303. package/build/dist/Server/Utils/PasswordHash.js +25 -4
  304. package/build/dist/Server/Utils/PasswordHash.js.map +1 -1
  305. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  306. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  307. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  308. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  309. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  310. package/build/dist/Types/HashedString.js +4 -3
  311. package/build/dist/Types/HashedString.js.map +1 -1
  312. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  313. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  314. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  315. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  316. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  317. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  318. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  319. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  320. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  321. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  322. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  323. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  324. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  325. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  326. package/build/dist/Types/Permission.js +23 -155
  327. package/build/dist/Types/Permission.js.map +1 -1
  328. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  329. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  330. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  331. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  332. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  333. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  334. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  335. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  336. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  338. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  339. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  340. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  343. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  344. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  345. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  346. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  347. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  348. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  349. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  350. package/build/dist/UI/Utils/Project.js +3 -0
  351. package/build/dist/UI/Utils/Project.js.map +1 -1
  352. package/build/dist/UI/Utils/StatusPage.js +4 -4
  353. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  354. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  355. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  356. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  357. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  358. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  359. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  360. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  361. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  362. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  363. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  364. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  365. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  366. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  367. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  368. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  369. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  370. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  371. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  372. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  373. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  374. package/package.json +1 -1
@@ -1,7 +1,13 @@
1
1
  import ObjectID from "../../../../Types/ObjectID";
2
2
  import AIRunType from "../../../../Types/AI/AIRunType";
3
3
  import AIRunStatus from "../../../../Types/AI/AIRunStatus";
4
+ import AIRunCodeFixRecommendation from "../../../../Types/AI/AIRunCodeFixRecommendation";
5
+ import CodeFixTaskContext, {
6
+ getInvestigationCodeFixTaskSnapshot,
7
+ InvestigationCodeFixTaskSnapshot,
8
+ } from "../../../../Types/AI/CodeFixTaskContext";
4
9
  import CodeFixTaskType from "../../../../Types/AI/CodeFixTaskType";
10
+ import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
5
11
  import BadDataException from "../../../../Types/Exception/BadDataException";
6
12
  import AIRun from "../../../../Models/DatabaseModels/AIRun";
7
13
  import Project from "../../../../Models/DatabaseModels/Project";
@@ -9,6 +15,7 @@ import AIRunService from "../../../Services/AIRunService";
9
15
  import ProjectService from "../../../Services/ProjectService";
10
16
  import FixRunBudget, { FixRunBudgetDecision } from "../CodeFix/FixRunBudget";
11
17
  import SubjectCodeFixRun from "./SubjectCodeFixRun";
18
+ import PostedRootCause from "./PostedRootCause";
12
19
  import logger from "../../Logger";
13
20
  import CaptureSpan from "../../Telemetry/CaptureSpan";
14
21
 
@@ -17,28 +24,32 @@ import CaptureSpan from "../../Telemetry/CaptureSpan";
17
24
  * capability, vision §4.8), in two forms:
18
25
  *
19
26
  * HUMAN-TRIGGERED: after an AI investigation posts a root-cause analysis on
20
- * an incident or alert, the user can click "Open Fix PR from this analysis"
21
- * on the investigation panel: the agent takes the posted analysis (the
22
- * RootCause feed item) as its entire context and opens a fix pull request.
23
- * No project opt-in flag is needed for this form: the human in the loop IS
24
- * the gate (G11 posture preserved). It runs inside a user-facing endpoint
25
- * (POST /ai-investigation/create-fix-task) and FAILS EARLY with a clear
26
- * message when a gate is not met.
27
+ * an incident or alert and records a Recommended code-fix decision, the user
28
+ * can click "Open Fix PR from this analysis" on the investigation panel: the
29
+ * agent takes the immutable stored copy of that posted analysis as its
30
+ * context and opens a fix pull request. No project opt-in flag is needed for
31
+ * this form, but the durable recommendation remains a server-side gate so a
32
+ * stale or forged client cannot turn a non-code investigation into a PR.
27
33
  *
28
- * AUTOMATIC: for projects that opted in (Project.enableAutomaticCodeFixes,
29
- * default FALSE — G11 posture: autonomous PR creation is opt-in only), an
30
- * investigation that ends with a POSITIVE confident classification (per the
31
- * structured G6 confidence signal, never the analysis prose) enqueues the
32
- * same FixFromIncident task with no human click. Like its
33
- * InstrumentationTaskTrigger sibling it is fire-and-forget inside the
34
- * investigation's postAnalysis and never throws. The PR still opens as a
34
+ * AUTOMATIC: for projects that opted in through the subject lane's incident
35
+ * or alert automatic-code-fix setting (default FALSE — G11 posture:
36
+ * autonomous PR creation is opt-in only), an
37
+ * investigation that ends with a POSITIVE code-fix classification (per the
38
+ * structured G6 signal, never a regex over the analysis prose) enqueues the
39
+ * same FixFromIncident task with no human click. Confidence alone is not
40
+ * sufficient: operational and other non-code causes do not open PRs. Like its
41
+ * InstrumentationTaskTrigger sibling it runs only after the Recommended
42
+ * decision and snapshot are durable, and it never throws. The PR still opens as a
35
43
  * DRAFT and is always human-reviewed — the opt-in moves the human gate from
36
44
  * PR creation to PR review, never past it.
37
45
  */
38
46
 
39
47
  export interface AutoFixTaskGateInput {
40
- // The project row with enableAi + enableAutomaticCodeFixes selected.
48
+ // The project row with enableAi + the subject lane's opt-in selected.
41
49
  project: Project | null;
50
+ // Exactly one subject selects the incident or alert opt-in.
51
+ incidentId?: ObjectID | undefined;
52
+ alertId?: ObjectID | undefined;
42
53
  // Whether the project has at least one GitHub-App-connected repository.
43
54
  hasConnectedRepository: boolean;
44
55
  // A non-terminal FixFromIncident run for the same subject, if any.
@@ -59,19 +70,27 @@ export default class FixFromIncidentTaskTrigger {
59
70
  * incidentId/alertId is expected; userId is the clicking user
60
71
  * (attribution on the run).
61
72
  *
62
- * Throws BadDataException naming the failed gate: no completed
63
- * investigation, no GitHub-App repository, or a duplicate active run.
73
+ * Throws BadDataException naming the failed gate: no latest
74
+ * completed/recommended investigation, no GitHub-App repository, or a
75
+ * duplicate active run.
64
76
  */
65
77
  @CaptureSpan()
66
78
  public static async createFixTaskFromInvestigation(data: {
67
79
  projectId: ObjectID;
80
+ investigationRunId: ObjectID;
68
81
  incidentId?: ObjectID | undefined;
69
82
  alertId?: ObjectID | undefined;
70
83
  userId: ObjectID;
71
84
  }): Promise<AIRun> {
72
- if (!data.incidentId && !data.alertId) {
85
+ if (!data.investigationRunId) {
73
86
  throw new BadDataException(
74
- "An incident or alert subject is required to create a fix task.",
87
+ "An investigation run id is required to create a fix task.",
88
+ );
89
+ }
90
+
91
+ if (Boolean(data.incidentId) === Boolean(data.alertId)) {
92
+ throw new BadDataException(
93
+ "Exactly one incident or alert subject is required to create a fix task.",
75
94
  );
76
95
  }
77
96
 
@@ -80,28 +99,119 @@ export default class FixFromIncidentTaskTrigger {
80
99
  : "alert";
81
100
 
82
101
  /*
83
- * Gate 1: a COMPLETED investigation must exist for the subject its
84
- * posted analysis (the RootCause feed item) is the fix task's entire
85
- * context. Without one the worker would have nothing to work from.
102
+ * Gate 1: inspect the LATEST investigation for the subject, matching the
103
+ * run shown by the dashboard panel. Its durable recommendation is the
104
+ * server-authored decision about whether a code fix is appropriate, and
105
+ * its taskContext carries the exact posted analysis that decision covered.
106
+ * An older Recommended run must never override a newer NotRecommended,
107
+ * Running or failed result.
86
108
  */
87
- const completedInvestigation: AIRun | null = await AIRunService.findOneBy({
109
+ const latestInvestigation: AIRun | null = await AIRunService.findOneBy({
88
110
  query: {
111
+ projectId: data.projectId,
89
112
  runType: AIRunType.Investigation,
90
- status: AIRunStatus.Completed,
91
113
  ...(data.incidentId
92
114
  ? { triggeredByIncidentId: data.incidentId }
93
115
  : { triggeredByAlertId: data.alertId! }),
94
116
  },
95
- select: { _id: true },
117
+ select: {
118
+ _id: true,
119
+ completedAt: true,
120
+ status: true,
121
+ codeFixRecommendation: true,
122
+ taskContext: true,
123
+ },
124
+ sort: { createdAt: SortOrder.Descending },
96
125
  props: { isRoot: true },
97
126
  });
98
127
 
99
- if (!completedInvestigation) {
128
+ if (!latestInvestigation) {
100
129
  throw new BadDataException(
101
130
  `No completed AI investigation exists for this ${subjectLabel} — the fix task uses the investigation's posted analysis as its context. Wait for the investigation to complete, or enable AI investigations in the AI settings.`,
102
131
  );
103
132
  }
104
133
 
134
+ if (
135
+ latestInvestigation.id?.toString() !== data.investigationRunId.toString()
136
+ ) {
137
+ throw new BadDataException(
138
+ `A newer AI investigation is now available for this ${subjectLabel}. Refresh the page before creating a fix task.`,
139
+ );
140
+ }
141
+
142
+ if (latestInvestigation.status !== AIRunStatus.Completed) {
143
+ throw new BadDataException(
144
+ `The latest AI investigation for this ${subjectLabel} has not completed, so a fix task cannot be created from an older analysis. Wait for the latest investigation to complete successfully.`,
145
+ );
146
+ }
147
+
148
+ if (
149
+ latestInvestigation.codeFixRecommendation ===
150
+ AIRunCodeFixRecommendation.Pending
151
+ ) {
152
+ throw new BadDataException(
153
+ `The latest AI investigation for this ${subjectLabel} is still deciding whether a code fix is appropriate. Wait for that recommendation to finish before creating a fix task.`,
154
+ );
155
+ }
156
+
157
+ if (
158
+ latestInvestigation.codeFixRecommendation !==
159
+ AIRunCodeFixRecommendation.Recommended
160
+ ) {
161
+ throw new BadDataException(
162
+ `The latest AI investigation for this ${subjectLabel} did not recommend a code fix, so a fix pull request task cannot be created from it.`,
163
+ );
164
+ }
165
+
166
+ /*
167
+ * Gate the same immutable pair the worker will consume. A Recommended
168
+ * row without a complete snapshot (or whose snapshot names another run)
169
+ * is unsafe: looking up the subject's latest feed item would allow a
170
+ * later investigation to change the task after this authorization check.
171
+ */
172
+ const investigationSnapshot: InvestigationCodeFixTaskSnapshot | null =
173
+ getInvestigationCodeFixTaskSnapshot(latestInvestigation.taskContext);
174
+
175
+ if (
176
+ !latestInvestigation.id ||
177
+ !investigationSnapshot ||
178
+ investigationSnapshot.investigationRunId !==
179
+ latestInvestigation.id.toString()
180
+ ) {
181
+ throw new BadDataException(
182
+ `The latest AI investigation for this ${subjectLabel} has no complete stored analysis snapshot, so a fix task cannot be created safely. Run a new investigation and try again.`,
183
+ );
184
+ }
185
+
186
+ /*
187
+ * The feed item is the published report the user actually saw. Resolve
188
+ * it by the exact run association added to the feed model, then require
189
+ * it to match the durable recommendation snapshot. A missing or
190
+ * mismatched report fails closed instead of silently borrowing a newer
191
+ * subject-level RootCause.
192
+ */
193
+ const analysisMarkdown: string | null =
194
+ await PostedRootCause.getForInvestigation({
195
+ incidentId: data.incidentId,
196
+ alertId: data.alertId,
197
+ aiRunId: data.investigationRunId,
198
+ runCompletedAt: latestInvestigation.completedAt,
199
+ });
200
+
201
+ if (!analysisMarkdown) {
202
+ throw new BadDataException(
203
+ `No posted investigation analysis exists for this ${subjectLabel} and investigation run. Refresh the page and wait for the report to finish publishing before creating a fix task.`,
204
+ );
205
+ }
206
+
207
+ if (
208
+ analysisMarkdown !== investigationSnapshot.investigationAnalysisMarkdown
209
+ ) {
210
+ throw new BadDataException(
211
+ `The posted investigation analysis for this ${subjectLabel} does not match its durable recommendation snapshot. Run a new investigation before creating a fix task.`,
212
+ );
213
+ }
214
+
105
215
  // Gate 2: a repository the agent can actually open a PR against.
106
216
  const hasConnectedRepository: boolean =
107
217
  await SubjectCodeFixRun.hasGitHubAppConnectedRepository(data.projectId);
@@ -136,6 +246,10 @@ export default class FixFromIncidentTaskTrigger {
136
246
  incidentId: data.incidentId,
137
247
  alertId: data.alertId,
138
248
  userId: data.userId,
249
+ taskContext: {
250
+ sourceInvestigationRunId: data.investigationRunId.toString(),
251
+ sourceInvestigationAnalysisMarkdown: analysisMarkdown,
252
+ },
139
253
  });
140
254
  }
141
255
 
@@ -143,9 +257,8 @@ export default class FixFromIncidentTaskTrigger {
143
257
  * The pure trigger decision for the AUTOMATIC form, separated from IO so
144
258
  * it can be tested directly: strict opt-in (default FALSE), a repository
145
259
  * the agent can actually open a PR against, and the per-subject dedupe
146
- * guard. The caller has already established the confident-investigation
147
- * prerequisite (this runs inside the investigation's postAnalysis, gated
148
- * by AIConfidenceSignal.shouldAutoEnqueueCodeFixTask).
260
+ * guard. The caller has already established and durably persisted the
261
+ * code-fix-recommended investigation prerequisite.
149
262
  */
150
263
  public static shouldAutoEnqueueFixTask(
151
264
  input: AutoFixTaskGateInput,
@@ -162,10 +275,21 @@ export default class FixFromIncidentTaskTrigger {
162
275
  * Strict opt-in — the column defaults to false, so unset/legacy rows
163
276
  * never enqueue. Autonomous PR creation must never be default-on.
164
277
  */
165
- if (input.project.enableAutomaticCodeFixes !== true) {
278
+ if (Boolean(input.incidentId) === Boolean(input.alertId)) {
279
+ return {
280
+ enqueue: false,
281
+ reason: "exactly one incident or alert subject is required",
282
+ };
283
+ }
284
+
285
+ const automaticCodeFixesEnabled: boolean = input.incidentId
286
+ ? input.project.enableAutomaticIncidentCodeFixes === true
287
+ : input.project.enableAutomaticAlertCodeFixes === true;
288
+
289
+ if (!automaticCodeFixesEnabled) {
166
290
  return {
167
291
  enqueue: false,
168
- reason: "project has not opted in to automatic code fixes",
292
+ reason: `project has not opted in to automatic ${input.incidentId ? "incident" : "alert"} code fixes`,
169
293
  };
170
294
  }
171
295
 
@@ -197,31 +321,52 @@ export default class FixFromIncidentTaskTrigger {
197
321
 
198
322
  /*
199
323
  * The AUTOMATIC form: enqueue a FixFromIncident run for a subject whose
200
- * investigation just posted a CONFIDENT analysis. Exactly one of
324
+ * latest investigation durably recommends a repository code fix. Exactly one of
201
325
  * incidentId/alertId is expected. NEVER throws — every failure is logged
202
- * and swallowed, because this runs inside the investigation's
203
- * postAnalysis and must not fail it. No userId: the run stays
326
+ * and swallowed, because this is a best-effort post-recommendation
327
+ * follow-up and must not fail the investigation. No userId: the run stays
204
328
  * system-authored.
205
329
  */
206
330
  @CaptureSpan()
207
- public static async autoEnqueueFromConfidentInvestigation(data: {
331
+ public static async autoEnqueueFromRecommendedInvestigation(data: {
208
332
  projectId: ObjectID;
333
+ investigationRunId: ObjectID;
334
+ analysisMarkdown: string;
209
335
  incidentId?: ObjectID | undefined;
210
336
  alertId?: ObjectID | undefined;
211
337
  }): Promise<void> {
212
338
  const { projectId } = data;
213
339
 
214
340
  try {
215
- if (!data.incidentId && !data.alertId) {
341
+ if (Boolean(data.incidentId) === Boolean(data.alertId)) {
342
+ return;
343
+ }
344
+
345
+ const taskContext: CodeFixTaskContext = {
346
+ sourceInvestigationRunId: data.investigationRunId?.toString(),
347
+ sourceInvestigationAnalysisMarkdown: data.analysisMarkdown,
348
+ };
349
+ const investigationSnapshot: InvestigationCodeFixTaskSnapshot | null =
350
+ getInvestigationCodeFixTaskSnapshot(taskContext);
351
+
352
+ if (!investigationSnapshot) {
353
+ logger.error(
354
+ `AI: not auto-enqueueing fix task for project ${projectId.toString()} — the recommended investigation has no complete stored analysis snapshot.`,
355
+ );
216
356
  return;
217
357
  }
218
358
 
219
359
  const project: Project | null = await ProjectService.findOneById({
220
360
  id: projectId,
221
- select: {
222
- enableAi: true,
223
- enableAutomaticCodeFixes: true,
224
- },
361
+ select: data.incidentId
362
+ ? {
363
+ enableAi: true,
364
+ enableAutomaticIncidentCodeFixes: true,
365
+ }
366
+ : {
367
+ enableAi: true,
368
+ enableAutomaticAlertCodeFixes: true,
369
+ },
225
370
  props: { isRoot: true },
226
371
  });
227
372
 
@@ -232,6 +377,8 @@ export default class FixFromIncidentTaskTrigger {
232
377
  const optInDecision: AutoFixTaskGateDecision =
233
378
  this.shouldAutoEnqueueFixTask({
234
379
  project,
380
+ incidentId: data.incidentId,
381
+ alertId: data.alertId,
235
382
  hasConnectedRepository: true,
236
383
  existingRun: null,
237
384
  });
@@ -243,17 +390,73 @@ export default class FixFromIncidentTaskTrigger {
243
390
  return;
244
391
  }
245
392
 
393
+ /*
394
+ * Re-read the authoritative latest source after the engine has durably
395
+ * settled it. This prevents an older overlapping investigation from
396
+ * auto-authorizing a task after a newer run became authoritative, and
397
+ * guarantees a task is never claimable while its source is Pending.
398
+ */
399
+ const latestInvestigation: AIRun | null = await AIRunService.findOneBy({
400
+ query: {
401
+ projectId,
402
+ runType: AIRunType.Investigation,
403
+ ...(data.incidentId
404
+ ? { triggeredByIncidentId: data.incidentId }
405
+ : { triggeredByAlertId: data.alertId! }),
406
+ },
407
+ select: {
408
+ _id: true,
409
+ status: true,
410
+ codeFixRecommendation: true,
411
+ taskContext: true,
412
+ },
413
+ sort: { createdAt: SortOrder.Descending },
414
+ props: { isRoot: true },
415
+ });
416
+ const persistedSnapshot: InvestigationCodeFixTaskSnapshot | null =
417
+ getInvestigationCodeFixTaskSnapshot(latestInvestigation?.taskContext);
418
+
419
+ if (
420
+ !latestInvestigation?.id ||
421
+ latestInvestigation.id.toString() !==
422
+ data.investigationRunId.toString() ||
423
+ latestInvestigation.status !== AIRunStatus.Completed ||
424
+ latestInvestigation.codeFixRecommendation !==
425
+ AIRunCodeFixRecommendation.Recommended ||
426
+ !persistedSnapshot ||
427
+ persistedSnapshot.investigationRunId !==
428
+ data.investigationRunId.toString() ||
429
+ persistedSnapshot.investigationAnalysisMarkdown !==
430
+ investigationSnapshot.investigationAnalysisMarkdown
431
+ ) {
432
+ logger.debug(
433
+ `AI: not auto-enqueueing fix task for project ${projectId.toString()} — the source is no longer the latest durably Recommended investigation.`,
434
+ );
435
+ return;
436
+ }
437
+
246
438
  /*
247
439
  * G11 guardrail: the per-project daily fix-run budget. For this
248
440
  * AUTOMATIC trigger, over-budget is a logged skip — never an error
249
441
  * thrown into the investigation.
250
442
  */
251
- const budget: FixRunBudgetDecision =
252
- await FixRunBudget.getBudgetStatus(projectId);
443
+ const budget: FixRunBudgetDecision = await FixRunBudget.getBudgetStatus(
444
+ projectId,
445
+ {
446
+ incidentId: data.incidentId,
447
+ alertId: data.alertId,
448
+ },
449
+ );
253
450
 
254
451
  if (!budget.allowed) {
255
452
  logger.debug(
256
- `AI: not auto-enqueueing fix task for project ${projectId.toString()} — ${FixRunBudget.describeRejection(budget)}`,
453
+ `AI: not auto-enqueueing fix task for project ${projectId.toString()} — ${FixRunBudget.describeRejection(
454
+ budget,
455
+ {
456
+ incidentId: data.incidentId,
457
+ alertId: data.alertId,
458
+ },
459
+ )}`,
257
460
  );
258
461
  return;
259
462
  }
@@ -270,6 +473,8 @@ export default class FixFromIncidentTaskTrigger {
270
473
 
271
474
  const decision: AutoFixTaskGateDecision = this.shouldAutoEnqueueFixTask({
272
475
  project,
476
+ incidentId: data.incidentId,
477
+ alertId: data.alertId,
273
478
  hasConnectedRepository,
274
479
  existingRun,
275
480
  });
@@ -287,6 +492,10 @@ export default class FixFromIncidentTaskTrigger {
287
492
  taskType: CodeFixTaskType.FixFromIncident,
288
493
  incidentId: data.incidentId,
289
494
  alertId: data.alertId,
495
+ taskContext: {
496
+ sourceInvestigationRunId: data.investigationRunId.toString(),
497
+ sourceInvestigationAnalysisMarkdown: data.analysisMarkdown,
498
+ },
290
499
  });
291
500
 
292
501
  logger.debug(
@@ -216,6 +216,8 @@ export default class AIIncidentInvestigationRunner {
216
216
  projectId,
217
217
  monitorId: QueryHelper.any(monitorIds),
218
218
  runType: AIRunType.Investigation,
219
+ triggeredByIncidentId: QueryHelper.notNull(),
220
+ triggeredByAlertId: QueryHelper.isNull(),
219
221
  createdAt: QueryHelper.greaterThan(windowStart),
220
222
  },
221
223
  props: { isRoot: true },
@@ -349,7 +351,9 @@ export default class AIIncidentInvestigationRunner {
349
351
  request: {
350
352
  // Persisted LlmLog label — owned by AIService (G4 budget list).
351
353
  feature: AI_INCIDENT_INVESTIGATION_FEATURE,
354
+ incidentId,
352
355
  contextSummary,
356
+ persistCodeFixRecommendation: true,
353
357
  postAnalysis: async (postData: {
354
358
  analysisMarkdown: string;
355
359
  confidence: ConfidenceSignal;
@@ -358,6 +362,7 @@ export default class AIIncidentInvestigationRunner {
358
362
  await IncidentFeedService.createIncidentFeedItem({
359
363
  incidentId,
360
364
  projectId,
365
+ aiRunId,
361
366
  incidentFeedEventType: IncidentFeedEventType.RootCause,
362
367
  displayColor: Blue500,
363
368
  feedInfoInMarkdown: postData.analysisMarkdown,
@@ -421,7 +426,7 @@ export default class AIIncidentInvestigationRunner {
421
426
 
422
427
  /*
423
428
  * Inconclusive means the telemetry was insufficient — for
424
- * opted-in projects (Project.enableInstrumentationFixTasks,
429
+ * opted-in projects (the incident instrumentation-fix setting,
425
430
  * default false), queue an ImproveInstrumentation fix task that
426
431
  * opens a PR adding the missing observability. Runs strictly
427
432
  * AFTER the analysis is posted, and the trigger never throws, so
@@ -442,29 +447,25 @@ export default class AIIncidentInvestigationRunner {
442
447
  },
443
448
  );
444
449
  }
445
-
446
- /*
447
- * The confident twin: a POSITIVE confident classification means
448
- * the posted analysis asserts an evidenced root cause — for
449
- * opted-in projects (Project.enableAutomaticCodeFixes, default
450
- * false), automatically queue the FixFromIncident task that
451
- * opens a draft fix PR from this analysis (the automatic form
452
- * of the "Open Fix PR from this analysis" button). Runs strictly
453
- * AFTER the analysis is posted because the posted RootCause feed
454
- * item IS the fix task's entire context, and the trigger never
455
- * throws. Fail direction (G6): the deterministic floor and a
456
- * failed classification never auto-open a PR.
457
- */
458
- if (
459
- AIConfidenceSignal.shouldAutoEnqueueCodeFixTask(postData.confidence)
460
- ) {
461
- await FixFromIncidentTaskTrigger.autoEnqueueFromConfidentInvestigation(
462
- {
463
- projectId,
464
- incidentId,
465
- },
466
- );
467
- }
450
+ },
451
+ /*
452
+ * The engine calls this only after it atomically persists Recommended
453
+ * with the exact posted analysis snapshot. That durable decision is
454
+ * the prerequisite for the optional automatic FixFromIncident task;
455
+ * the trigger then applies the incident lane's independent opt-in and
456
+ * remaining repository, budget and dedupe gates.
457
+ */
458
+ onCodeFixRecommended: async (data: {
459
+ analysisMarkdown: string;
460
+ }): Promise<void> => {
461
+ await FixFromIncidentTaskTrigger.autoEnqueueFromRecommendedInvestigation(
462
+ {
463
+ projectId,
464
+ investigationRunId: aiRunId,
465
+ analysisMarkdown: data.analysisMarkdown,
466
+ incidentId,
467
+ },
468
+ );
468
469
  },
469
470
  /*
470
471
  * RCA-first ordering: auto-remediation for this incident was
@@ -15,8 +15,8 @@ import CaptureSpan from "../../Telemetry/CaptureSpan";
15
15
  * confidence signal (ConfidenceSignal.ts), never the analysis prose — the
16
16
  * telemetry itself is the bug: the code paths involved were not observable
17
17
  * enough to diagnose. For projects that opted in
18
- * (Project.enableInstrumentationFixTasks, default FALSE — G11 posture:
19
- * autonomous PR creation is opt-in only), the inconclusive analysis becomes
18
+ * (the subject lane's incident/alert instrumentation setting, default FALSE
19
+ * — G11 posture: autonomous PR creation is opt-in only), the inconclusive analysis becomes
20
20
  * the input to a CodeFix AIRun (codeFixTaskType: ImproveInstrumentation)
21
21
  * that the agent worker turns into a pull request adding the missing
22
22
  * observability — so the NEXT investigation of a similar signal can reach a
@@ -28,8 +28,11 @@ import CaptureSpan from "../../Telemetry/CaptureSpan";
28
28
  */
29
29
 
30
30
  export interface InstrumentationTaskGateInput {
31
- // The project row with enableAi + enableInstrumentationFixTasks selected.
31
+ // The project row with enableAi + the subject lane's opt-in selected.
32
32
  project: Project | null;
33
+ // Exactly one subject selects the incident or alert opt-in.
34
+ incidentId?: ObjectID | undefined;
35
+ alertId?: ObjectID | undefined;
33
36
  // Whether the project has at least one GitHub-App-connected repository.
34
37
  hasConnectedRepository: boolean;
35
38
  // A non-terminal ImproveInstrumentation run for the same subject, if any.
@@ -63,10 +66,21 @@ export default class InstrumentationTaskTrigger {
63
66
  * Strict opt-in — the column defaults to false, so unset/legacy rows
64
67
  * never enqueue. Autonomous PR creation must never be default-on.
65
68
  */
66
- if (input.project.enableInstrumentationFixTasks !== true) {
69
+ if (Boolean(input.incidentId) === Boolean(input.alertId)) {
67
70
  return {
68
71
  enqueue: false,
69
- reason: "project has not opted in to instrumentation fix tasks",
72
+ reason: "exactly one incident or alert subject is required",
73
+ };
74
+ }
75
+
76
+ const instrumentationFixTasksEnabled: boolean = input.incidentId
77
+ ? input.project.enableIncidentInstrumentationFixTasks === true
78
+ : input.project.enableAlertInstrumentationFixTasks === true;
79
+
80
+ if (!instrumentationFixTasksEnabled) {
81
+ return {
82
+ enqueue: false,
83
+ reason: `project has not opted in to ${input.incidentId ? "incident" : "alert"} instrumentation fix tasks`,
70
84
  };
71
85
  }
72
86
 
@@ -112,16 +126,21 @@ export default class InstrumentationTaskTrigger {
112
126
  const { projectId } = data;
113
127
 
114
128
  try {
115
- if (!data.incidentId && !data.alertId) {
129
+ if (Boolean(data.incidentId) === Boolean(data.alertId)) {
116
130
  return;
117
131
  }
118
132
 
119
133
  const project: Project | null = await ProjectService.findOneById({
120
134
  id: projectId,
121
- select: {
122
- enableAi: true,
123
- enableInstrumentationFixTasks: true,
124
- },
135
+ select: data.incidentId
136
+ ? {
137
+ enableAi: true,
138
+ enableIncidentInstrumentationFixTasks: true,
139
+ }
140
+ : {
141
+ enableAi: true,
142
+ enableAlertInstrumentationFixTasks: true,
143
+ },
125
144
  props: { isRoot: true },
126
145
  });
127
146
 
@@ -132,6 +151,8 @@ export default class InstrumentationTaskTrigger {
132
151
  const optInDecision: InstrumentationTaskGateDecision =
133
152
  this.shouldEnqueueInstrumentationTask({
134
153
  project,
154
+ incidentId: data.incidentId,
155
+ alertId: data.alertId,
135
156
  hasConnectedRepository: true,
136
157
  existingRun: null,
137
158
  });
@@ -150,12 +171,23 @@ export default class InstrumentationTaskTrigger {
150
171
  * throw the same rejection, but that lands in the catch below as an
151
172
  * error log; a budget skip is expected behavior, not a failure).
152
173
  */
153
- const budget: FixRunBudgetDecision =
154
- await FixRunBudget.getBudgetStatus(projectId);
174
+ const budget: FixRunBudgetDecision = await FixRunBudget.getBudgetStatus(
175
+ projectId,
176
+ {
177
+ incidentId: data.incidentId,
178
+ alertId: data.alertId,
179
+ },
180
+ );
155
181
 
156
182
  if (!budget.allowed) {
157
183
  logger.debug(
158
- `AI: not enqueueing instrumentation task for project ${projectId.toString()} — ${FixRunBudget.describeRejection(budget)}`,
184
+ `AI: not enqueueing instrumentation task for project ${projectId.toString()} — ${FixRunBudget.describeRejection(
185
+ budget,
186
+ {
187
+ incidentId: data.incidentId,
188
+ alertId: data.alertId,
189
+ },
190
+ )}`,
159
191
  );
160
192
  return;
161
193
  }
@@ -177,6 +209,8 @@ export default class InstrumentationTaskTrigger {
177
209
  const decision: InstrumentationTaskGateDecision =
178
210
  this.shouldEnqueueInstrumentationTask({
179
211
  project,
212
+ incidentId: data.incidentId,
213
+ alertId: data.alertId,
180
214
  hasConnectedRepository,
181
215
  existingRun,
182
216
  });