@hotmeshio/long-tail 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/build/api/roles.d.ts +4 -0
  2. package/build/api/roles.js +7 -1
  3. package/build/api/workflows/config.d.ts +7 -1
  4. package/build/api/workflows/config.js +7 -1
  5. package/build/api/workflows/discovery.js +1 -4
  6. package/build/lib/db/schemas/019_role_priority.sql +28 -0
  7. package/build/lib/db/schemas/020_workflow_certified.sql +34 -0
  8. package/build/modules/ltconfig.d.ts +3 -2
  9. package/build/modules/ltconfig.js +4 -4
  10. package/build/routes/roles.js +1 -1
  11. package/build/routes/workflows/config.js +1 -0
  12. package/build/scripts/ortho-populate.d.ts +7 -1
  13. package/build/scripts/ortho-populate.js +21 -6
  14. package/build/services/config/cache.js +1 -0
  15. package/build/services/config/read.js +2 -0
  16. package/build/services/config/sql.d.ts +2 -2
  17. package/build/services/config/sql.js +6 -5
  18. package/build/services/config/write.js +13 -0
  19. package/build/services/escalation/bulk.d.ts +3 -1
  20. package/build/services/escalation/bulk.js +3 -1
  21. package/build/services/escalation/crud.d.ts +4 -3
  22. package/build/services/escalation/crud.js +4 -3
  23. package/build/services/escalation/facet-sql.d.ts +1 -0
  24. package/build/services/escalation/facet-sql.js +7 -6
  25. package/build/services/escalation/queries.js +27 -5
  26. package/build/services/escalation/sql.d.ts +19 -2
  27. package/build/services/escalation/sql.js +32 -9
  28. package/build/services/escalation/types.d.ts +7 -1
  29. package/build/services/role/index.js +2 -0
  30. package/build/services/role/sql.d.ts +4 -4
  31. package/build/services/role/sql.js +12 -6
  32. package/build/services/role/types.d.ts +14 -0
  33. package/build/start/workers.js +1 -0
  34. package/build/system/mcp-servers/admin/schemas.d.ts +9 -0
  35. package/build/system/mcp-servers/admin/schemas.js +6 -1
  36. package/build/system/mcp-servers/admin/users.js +4 -1
  37. package/build/system/mcp-servers/admin/workflow-config.js +1 -0
  38. package/build/system/seed/tool-manifests-admin.d.ts +152 -0
  39. package/build/system/seed/tool-manifests-admin.js +1 -1
  40. package/build/types/config.d.ts +16 -0
  41. package/build/types/startup.d.ts +11 -1
  42. package/dashboard/dist/assets/{AdminDashboard-C9eE1VEp.js → AdminDashboard-9JLg41f-.js} +2 -2
  43. package/dashboard/dist/assets/{AdminDashboard-C9eE1VEp.js.map → AdminDashboard-9JLg41f-.js.map} +1 -1
  44. package/dashboard/dist/assets/{AgentConfigPage-Ba8QfXM2.js → AgentConfigPage-D5P1hcOc.js} +6 -6
  45. package/dashboard/dist/assets/{AgentConfigPage-Ba8QfXM2.js.map → AgentConfigPage-D5P1hcOc.js.map} +1 -1
  46. package/dashboard/dist/assets/{AgentDetailPage-DVmec0CP.js → AgentDetailPage-DrijeAV8.js} +4 -4
  47. package/dashboard/dist/assets/{AgentDetailPage-DVmec0CP.js.map → AgentDetailPage-DrijeAV8.js.map} +1 -1
  48. package/dashboard/dist/assets/{AgentsPage-DNiCYMh3.js → AgentsPage-BW5d0JOt.js} +2 -2
  49. package/dashboard/dist/assets/{AgentsPage-DNiCYMh3.js.map → AgentsPage-BW5d0JOt.js.map} +1 -1
  50. package/dashboard/dist/assets/{AvailableEscalationsPage-gDIF8ocC.js → AvailableEscalationsPage-CoZ4Lufr.js} +2 -2
  51. package/dashboard/dist/assets/{AvailableEscalationsPage-gDIF8ocC.js.map → AvailableEscalationsPage-CoZ4Lufr.js.map} +1 -1
  52. package/dashboard/dist/assets/{BotPicker-3wBcBavT.js → BotPicker-xGUCxJo-.js} +2 -2
  53. package/dashboard/dist/assets/{BotPicker-3wBcBavT.js.map → BotPicker-xGUCxJo-.js.map} +1 -1
  54. package/dashboard/dist/assets/{CapabilitiesPage-WoPkND2y.js → CapabilitiesPage-ChaRJiyg.js} +2 -2
  55. package/dashboard/dist/assets/{CapabilitiesPage-WoPkND2y.js.map → CapabilitiesPage-ChaRJiyg.js.map} +1 -1
  56. package/dashboard/dist/assets/{CollapsibleSection-Cx99mqNN.js → CollapsibleSection-CXMPecjj.js} +2 -2
  57. package/dashboard/dist/assets/{CollapsibleSection-Cx99mqNN.js.map → CollapsibleSection-CXMPecjj.js.map} +1 -1
  58. package/dashboard/dist/assets/{CredentialsPage-DbNaoPbF.js → CredentialsPage-BbdfZh1D.js} +2 -2
  59. package/dashboard/dist/assets/{CredentialsPage-DbNaoPbF.js.map → CredentialsPage-BbdfZh1D.js.map} +1 -1
  60. package/dashboard/dist/assets/{CronLabel-DLW4_Zg4.js → CronLabel-CJUL50eO.js} +2 -2
  61. package/dashboard/dist/assets/{CronLabel-DLW4_Zg4.js.map → CronLabel-CJUL50eO.js.map} +1 -1
  62. package/dashboard/dist/assets/{CustomDurationPicker-BRUFjkiu.js → CustomDurationPicker-id6Tq64R.js} +2 -2
  63. package/dashboard/dist/assets/{CustomDurationPicker-BRUFjkiu.js.map → CustomDurationPicker-id6Tq64R.js.map} +1 -1
  64. package/dashboard/dist/assets/{DropZone-DEX0BBqt.js → DropZone-CZDmNBn-.js} +2 -2
  65. package/dashboard/dist/assets/{DropZone-DEX0BBqt.js.map → DropZone-CZDmNBn-.js.map} +1 -1
  66. package/dashboard/dist/assets/{ElapsedCell-BtmDQaym.js → ElapsedCell-B8TrnyT5.js} +2 -2
  67. package/dashboard/dist/assets/{ElapsedCell-BtmDQaym.js.map → ElapsedCell-B8TrnyT5.js.map} +1 -1
  68. package/dashboard/dist/assets/{EscalationSchemaPage-Bm4yBEGN.js → EscalationSchemaPage-C6UuZgCD.js} +2 -2
  69. package/dashboard/dist/assets/{EscalationSchemaPage-Bm4yBEGN.js.map → EscalationSchemaPage-C6UuZgCD.js.map} +1 -1
  70. package/dashboard/dist/assets/{EscalationsOverview-B3xZwTQA.js → EscalationsOverview-CjLyujJ3.js} +2 -2
  71. package/dashboard/dist/assets/{EscalationsOverview-B3xZwTQA.js.map → EscalationsOverview-CjLyujJ3.js.map} +1 -1
  72. package/dashboard/dist/assets/{EventTable-Bh9FKXLI.js → EventTable-D_rNmyGG.js} +2 -2
  73. package/dashboard/dist/assets/{EventTable-Bh9FKXLI.js.map → EventTable-D_rNmyGG.js.map} +1 -1
  74. package/dashboard/dist/assets/{GraphInvokePage-ov_ANlaE.js → GraphInvokePage-BMyrTnI6.js} +2 -2
  75. package/dashboard/dist/assets/{GraphInvokePage-ov_ANlaE.js.map → GraphInvokePage-BMyrTnI6.js.map} +1 -1
  76. package/dashboard/dist/assets/{HomePage-D0DV6izb.js → HomePage-MBv6pwk4.js} +2 -2
  77. package/dashboard/dist/assets/{HomePage-D0DV6izb.js.map → HomePage-MBv6pwk4.js.map} +1 -1
  78. package/dashboard/dist/assets/{ListToolbar-FpcvqNkN.js → ListToolbar--FkPpYDY.js} +2 -2
  79. package/dashboard/dist/assets/{ListToolbar-FpcvqNkN.js.map → ListToolbar--FkPpYDY.js.map} +1 -1
  80. package/dashboard/dist/assets/{McpOverview-DcuRiAff.js → McpOverview-CtAFXv-T.js} +2 -2
  81. package/dashboard/dist/assets/{McpOverview-DcuRiAff.js.map → McpOverview-CtAFXv-T.js.map} +1 -1
  82. package/dashboard/dist/assets/{McpQueryDetailPage-BcYl67KP.js → McpQueryDetailPage-5Jzz2q2g.js} +2 -2
  83. package/dashboard/dist/assets/{McpQueryDetailPage-BcYl67KP.js.map → McpQueryDetailPage-5Jzz2q2g.js.map} +1 -1
  84. package/dashboard/dist/assets/{McpQueryPage-C3GDzqZM.js → McpQueryPage-DveeRF5I.js} +2 -2
  85. package/dashboard/dist/assets/{McpQueryPage-C3GDzqZM.js.map → McpQueryPage-DveeRF5I.js.map} +1 -1
  86. package/dashboard/dist/assets/{McpRunDetailPage-SzOyhDBW.js → McpRunDetailPage-BYIxBcA7.js} +2 -2
  87. package/dashboard/dist/assets/{McpRunDetailPage-SzOyhDBW.js.map → McpRunDetailPage-BYIxBcA7.js.map} +1 -1
  88. package/dashboard/dist/assets/{McpRunsPage-BwgB6mRV.js → McpRunsPage-Cgke6ask.js} +2 -2
  89. package/dashboard/dist/assets/{McpRunsPage-BwgB6mRV.js.map → McpRunsPage-Cgke6ask.js.map} +1 -1
  90. package/dashboard/dist/assets/{NamespacePill-CwKdoyRM.js → NamespacePill-DlqBTvFR.js} +2 -2
  91. package/dashboard/dist/assets/{NamespacePill-CwKdoyRM.js.map → NamespacePill-DlqBTvFR.js.map} +1 -1
  92. package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js +2 -0
  93. package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js.map +1 -0
  94. package/dashboard/dist/assets/{OperatorDashboard-DSXh-yYw.js → OperatorDashboard-DMQwodfo.js} +2 -2
  95. package/dashboard/dist/assets/{OperatorDashboard-DSXh-yYw.js.map → OperatorDashboard-DMQwodfo.js.map} +1 -1
  96. package/dashboard/dist/assets/{PageHeader-BhaWTWcM.js → PageHeader-CFta2VaS.js} +2 -2
  97. package/dashboard/dist/assets/{PageHeader-BhaWTWcM.js.map → PageHeader-CFta2VaS.js.map} +1 -1
  98. package/dashboard/dist/assets/{PageHeaderWithStats-yex5WmHB.js → PageHeaderWithStats-CcVAji-7.js} +2 -2
  99. package/dashboard/dist/assets/{PageHeaderWithStats-yex5WmHB.js.map → PageHeaderWithStats-CcVAji-7.js.map} +1 -1
  100. package/dashboard/dist/assets/{ProcessDetailPage-iIB1rwEt.js → ProcessDetailPage-Dodrk5-z.js} +2 -2
  101. package/dashboard/dist/assets/{ProcessDetailPage-iIB1rwEt.js.map → ProcessDetailPage-Dodrk5-z.js.map} +1 -1
  102. package/dashboard/dist/assets/{ProcessesListPage-BrqWR2zr.js → ProcessesListPage-BVtkWVLY.js} +2 -2
  103. package/dashboard/dist/assets/{ProcessesListPage-BrqWR2zr.js.map → ProcessesListPage-BVtkWVLY.js.map} +1 -1
  104. package/dashboard/dist/assets/RoleDetailPage-8NldZI49.js +11 -0
  105. package/dashboard/dist/assets/RoleDetailPage-8NldZI49.js.map +1 -0
  106. package/dashboard/dist/assets/{RolePill-Cl71eDUA.js → RolePill-CXEyPMqb.js} +2 -2
  107. package/dashboard/dist/assets/{RolePill-Cl71eDUA.js.map → RolePill-CXEyPMqb.js.map} +1 -1
  108. package/dashboard/dist/assets/{RolesPage-Bzp9FhAl.js → RolesPage-BJBjtFNY.js} +2 -2
  109. package/dashboard/dist/assets/{RolesPage-Bzp9FhAl.js.map → RolesPage-BJBjtFNY.js.map} +1 -1
  110. package/dashboard/dist/assets/{RunAsSelector-DXbHRxQs.js → RunAsSelector-Cc1i017Z.js} +2 -2
  111. package/dashboard/dist/assets/{RunAsSelector-DXbHRxQs.js.map → RunAsSelector-Cc1i017Z.js.map} +1 -1
  112. package/dashboard/dist/assets/{StickyPagination-D8XuMSWD.js → StickyPagination-GQKFFTjL.js} +2 -2
  113. package/dashboard/dist/assets/{StickyPagination-D8XuMSWD.js.map → StickyPagination-GQKFFTjL.js.map} +1 -1
  114. package/dashboard/dist/assets/{StreamMessageDetail-D5v95pmz.js → StreamMessageDetail-BYzfjWe_.js} +2 -2
  115. package/dashboard/dist/assets/{StreamMessageDetail-D5v95pmz.js.map → StreamMessageDetail-BYzfjWe_.js.map} +1 -1
  116. package/dashboard/dist/assets/{SwimlaneTimeline-CUEf2R5R.js → SwimlaneTimeline-DLVmRrd-.js} +2 -2
  117. package/dashboard/dist/assets/{SwimlaneTimeline-CUEf2R5R.js.map → SwimlaneTimeline-DLVmRrd-.js.map} +1 -1
  118. package/dashboard/dist/assets/{TagInput-B_WQiuer.js → TagInput-CQg-TrV9.js} +2 -2
  119. package/dashboard/dist/assets/{TagInput-B_WQiuer.js.map → TagInput-CQg-TrV9.js.map} +1 -1
  120. package/dashboard/dist/assets/{TaskDetailPage-BJvKNwEe.js → TaskDetailPage-HzQpzp6D.js} +2 -2
  121. package/dashboard/dist/assets/{TaskDetailPage-BJvKNwEe.js.map → TaskDetailPage-HzQpzp6D.js.map} +1 -1
  122. package/dashboard/dist/assets/{TaskQueuePill-Lgn2obNU.js → TaskQueuePill-DyvtL8X4.js} +2 -2
  123. package/dashboard/dist/assets/{TaskQueuePill-Lgn2obNU.js.map → TaskQueuePill-DyvtL8X4.js.map} +1 -1
  124. package/dashboard/dist/assets/{TasksListPage-CM7BWh_h.js → TasksListPage-DpqevgTz.js} +2 -2
  125. package/dashboard/dist/assets/{TasksListPage-CM7BWh_h.js.map → TasksListPage-DpqevgTz.js.map} +1 -1
  126. package/dashboard/dist/assets/{TimeAgo-D1K7xKq5.js → TimeAgo-CftB8aJE.js} +2 -2
  127. package/dashboard/dist/assets/{TimeAgo-D1K7xKq5.js.map → TimeAgo-CftB8aJE.js.map} +1 -1
  128. package/dashboard/dist/assets/{TimestampCell-7G0echgP.js → TimestampCell-BSKj1jqT.js} +2 -2
  129. package/dashboard/dist/assets/{TimestampCell-7G0echgP.js.map → TimestampCell-BSKj1jqT.js.map} +1 -1
  130. package/dashboard/dist/assets/{ToolPill-uVqcbHPE.js → ToolPill-miuRcj1Q.js} +2 -2
  131. package/dashboard/dist/assets/{ToolPill-uVqcbHPE.js.map → ToolPill-miuRcj1Q.js.map} +1 -1
  132. package/dashboard/dist/assets/{ToolTestPanel-LxuJvURK.js → ToolTestPanel-DVQICZUQ.js} +2 -2
  133. package/dashboard/dist/assets/{ToolTestPanel-LxuJvURK.js.map → ToolTestPanel-DVQICZUQ.js.map} +1 -1
  134. package/dashboard/dist/assets/{TopicDetailPage-JvAX6rrR.js → TopicDetailPage-B2LAQDEg.js} +2 -2
  135. package/dashboard/dist/assets/{TopicDetailPage-JvAX6rrR.js.map → TopicDetailPage-B2LAQDEg.js.map} +1 -1
  136. package/dashboard/dist/assets/{TopicsPage-tFT2AcTz.js → TopicsPage-SwPAnN2C.js} +2 -2
  137. package/dashboard/dist/assets/{TopicsPage-tFT2AcTz.js.map → TopicsPage-SwPAnN2C.js.map} +1 -1
  138. package/dashboard/dist/assets/{UserName-Djz0nmaZ.js → UserName-Ce9gvlT5.js} +2 -2
  139. package/dashboard/dist/assets/{UserName-Djz0nmaZ.js.map → UserName-Ce9gvlT5.js.map} +1 -1
  140. package/dashboard/dist/assets/{WorkflowExecutionPage-f53hilbI.js → WorkflowExecutionPage-BI9NzeaH.js} +2 -2
  141. package/dashboard/dist/assets/{WorkflowExecutionPage-f53hilbI.js.map → WorkflowExecutionPage-BI9NzeaH.js.map} +1 -1
  142. package/dashboard/dist/assets/{WorkflowPill-IDjTRfQ8.js → WorkflowPill-BuNkWUVM.js} +2 -2
  143. package/dashboard/dist/assets/WorkflowPill-BuNkWUVM.js.map +1 -0
  144. package/dashboard/dist/assets/{WorkflowsDashboard-DM9Xe665.js → WorkflowsDashboard-CvWSgQdE.js} +2 -2
  145. package/dashboard/dist/assets/{WorkflowsDashboard-DM9Xe665.js.map → WorkflowsDashboard-CvWSgQdE.js.map} +1 -1
  146. package/dashboard/dist/assets/{WorkflowsOverview-CUGSrx9N.js → WorkflowsOverview-CjBWlwlH.js} +2 -2
  147. package/dashboard/dist/assets/{WorkflowsOverview-CUGSrx9N.js.map → WorkflowsOverview-CjBWlwlH.js.map} +1 -1
  148. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B1_yqxAw.js → YamlWorkflowDetailPage-Ds5o1UK9.js} +2 -2
  149. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B1_yqxAw.js.map → YamlWorkflowDetailPage-Ds5o1UK9.js.map} +1 -1
  150. package/dashboard/dist/assets/{YamlWorkflowsPage-NtGvqiu7.js → YamlWorkflowsPage-ChwvZS4Z.js} +2 -2
  151. package/dashboard/dist/assets/{YamlWorkflowsPage-NtGvqiu7.js.map → YamlWorkflowsPage-ChwvZS4Z.js.map} +1 -1
  152. package/dashboard/dist/assets/{agents-tML6AjDj.js → agents-A1U43853.js} +2 -2
  153. package/dashboard/dist/assets/{agents-tML6AjDj.js.map → agents-A1U43853.js.map} +1 -1
  154. package/dashboard/dist/assets/{bots-Cb0WTwhY.js → bots-CyzN6Uxi.js} +2 -2
  155. package/dashboard/dist/assets/{bots-Cb0WTwhY.js.map → bots-CyzN6Uxi.js.map} +1 -1
  156. package/dashboard/dist/assets/{capabilities-BGZogsi_.js → capabilities-BE1X5FVI.js} +2 -2
  157. package/dashboard/dist/assets/{capabilities-BGZogsi_.js.map → capabilities-BE1X5FVI.js.map} +1 -1
  158. package/dashboard/dist/assets/{controlplane-B7VJTlZD.js → controlplane-BrwK_MT8.js} +2 -2
  159. package/dashboard/dist/assets/{controlplane-B7VJTlZD.js.map → controlplane-BrwK_MT8.js.map} +1 -1
  160. package/dashboard/dist/assets/{escalation-Bl-SQV_u.js → escalation-DDdt7UdU.js} +2 -2
  161. package/dashboard/dist/assets/{escalation-Bl-SQV_u.js.map → escalation-DDdt7UdU.js.map} +1 -1
  162. package/dashboard/dist/assets/{escalation-columns-BlJOswRx.js → escalation-columns-D_zFY1zF.js} +2 -2
  163. package/dashboard/dist/assets/{escalation-columns-BlJOswRx.js.map → escalation-columns-D_zFY1zF.js.map} +1 -1
  164. package/dashboard/dist/assets/{index-DcbEIXit.js → index-6MALVAEY.js} +2 -2
  165. package/dashboard/dist/assets/{index-DcbEIXit.js.map → index-6MALVAEY.js.map} +1 -1
  166. package/dashboard/dist/assets/{index-CBv3UxF2.js → index-BNWKksZ6.js} +2 -2
  167. package/dashboard/dist/assets/{index-CBv3UxF2.js.map → index-BNWKksZ6.js.map} +1 -1
  168. package/dashboard/dist/assets/{index-DfDfJivY.js → index-BtrNxebh.js} +2 -2
  169. package/dashboard/dist/assets/{index-DfDfJivY.js.map → index-BtrNxebh.js.map} +1 -1
  170. package/dashboard/dist/assets/{index-BorpZbZA.js → index-C-rJQ-vB.js} +2 -2
  171. package/dashboard/dist/assets/{index-BorpZbZA.js.map → index-C-rJQ-vB.js.map} +1 -1
  172. package/dashboard/dist/assets/{index-Il_g7kw5.js → index-CGUBekEU.js} +2 -2
  173. package/dashboard/dist/assets/{index-Il_g7kw5.js.map → index-CGUBekEU.js.map} +1 -1
  174. package/dashboard/dist/assets/{index-Dgw1KKpq.js → index-CKXSKsVZ.js} +4 -4
  175. package/dashboard/dist/assets/{index-Dgw1KKpq.js.map → index-CKXSKsVZ.js.map} +1 -1
  176. package/dashboard/dist/assets/{index-Wny0bRgq.css → index-CZ6-l8_0.css} +1 -1
  177. package/dashboard/dist/assets/{index--WeZDfeN.js → index-D2dDPGNk.js} +2 -2
  178. package/dashboard/dist/assets/{index--WeZDfeN.js.map → index-D2dDPGNk.js.map} +1 -1
  179. package/dashboard/dist/assets/{index-0o71lRuY.js → index-D4U--3Xo.js} +2 -2
  180. package/dashboard/dist/assets/{index-0o71lRuY.js.map → index-D4U--3Xo.js.map} +1 -1
  181. package/dashboard/dist/assets/{index-e97M6GoI.js → index-D4gAsCGh.js} +2 -2
  182. package/dashboard/dist/assets/{index-e97M6GoI.js.map → index-D4gAsCGh.js.map} +1 -1
  183. package/dashboard/dist/assets/{index-SCrD3l-K.js → index-DEXouwBQ.js} +2 -2
  184. package/dashboard/dist/assets/{index-SCrD3l-K.js.map → index-DEXouwBQ.js.map} +1 -1
  185. package/dashboard/dist/assets/{index-3A_5CL81.js → index-NnGsWGNS.js} +2 -2
  186. package/dashboard/dist/assets/{index-3A_5CL81.js.map → index-NnGsWGNS.js.map} +1 -1
  187. package/dashboard/dist/assets/index-U27KBbTV.js +9 -0
  188. package/dashboard/dist/assets/index-U27KBbTV.js.map +1 -0
  189. package/dashboard/dist/assets/index-fwHQSJCp.js +6 -0
  190. package/dashboard/dist/assets/index-fwHQSJCp.js.map +1 -0
  191. package/dashboard/dist/assets/{knowledge-CDzw4E6q.js → knowledge-B3ZIRTeu.js} +2 -2
  192. package/dashboard/dist/assets/{knowledge-CDzw4E6q.js.map → knowledge-B3ZIRTeu.js.map} +1 -1
  193. package/dashboard/dist/assets/{mcp-D_-NQtnG.js → mcp-BJjWiHdc.js} +2 -2
  194. package/dashboard/dist/assets/{mcp-D_-NQtnG.js.map → mcp-BJjWiHdc.js.map} +1 -1
  195. package/dashboard/dist/assets/{mcp-query-BqZXdf9A.js → mcp-query-ksjBztwq.js} +2 -2
  196. package/dashboard/dist/assets/{mcp-query-BqZXdf9A.js.map → mcp-query-ksjBztwq.js.map} +1 -1
  197. package/dashboard/dist/assets/{pipelines-CNLhgj8b.js → pipelines-DT1astmP.js} +2 -2
  198. package/dashboard/dist/assets/{pipelines-CNLhgj8b.js.map → pipelines-DT1astmP.js.map} +1 -1
  199. package/dashboard/dist/assets/{roles-CFD2eYap.js → roles-UboiQxXT.js} +2 -2
  200. package/dashboard/dist/assets/roles-UboiQxXT.js.map +1 -0
  201. package/dashboard/dist/assets/{tasks-DcSvF636.js → tasks-aL0K8WW3.js} +2 -2
  202. package/dashboard/dist/assets/{tasks-DcSvF636.js.map → tasks-aL0K8WW3.js.map} +1 -1
  203. package/dashboard/dist/assets/{topics-DI8TFSZv.js → topics-CZO06VJl.js} +2 -2
  204. package/dashboard/dist/assets/{topics-DI8TFSZv.js.map → topics-CZO06VJl.js.map} +1 -1
  205. package/dashboard/dist/assets/{useEventHooks-DcIgMDh3.js → useEventHooks-DlWkui_n.js} +2 -2
  206. package/dashboard/dist/assets/{useEventHooks-DcIgMDh3.js.map → useEventHooks-DlWkui_n.js.map} +1 -1
  207. package/dashboard/dist/assets/{useNamespace-C88ZxGoX.js → useNamespace-BBzCmCIN.js} +2 -2
  208. package/dashboard/dist/assets/{useNamespace-C88ZxGoX.js.map → useNamespace-BBzCmCIN.js.map} +1 -1
  209. package/dashboard/dist/assets/{useYamlActivityEvents-D2-yVjJ7.js → useYamlActivityEvents-ZS6wRSSc.js} +2 -2
  210. package/dashboard/dist/assets/{useYamlActivityEvents-D2-yVjJ7.js.map → useYamlActivityEvents-ZS6wRSSc.js.map} +1 -1
  211. package/dashboard/dist/assets/{users-C0WV36X8.js → users-Dzh04pRB.js} +2 -2
  212. package/dashboard/dist/assets/{users-C0WV36X8.js.map → users-Dzh04pRB.js.map} +1 -1
  213. package/dashboard/dist/assets/{vendor-icons-CEWCGPeJ.js → vendor-icons-BaQqUm-e.js} +2 -2
  214. package/dashboard/dist/assets/{vendor-icons-CEWCGPeJ.js.map → vendor-icons-BaQqUm-e.js.map} +1 -1
  215. package/dashboard/dist/assets/{workflows-CkPv7xk-.js → workflows-BTkHs6VT.js} +2 -2
  216. package/dashboard/dist/assets/workflows-BTkHs6VT.js.map +1 -0
  217. package/dashboard/dist/assets/{yaml-workflows-BjrMQLTK.js → yaml-workflows-Df8u3lgx.js} +2 -2
  218. package/dashboard/dist/assets/{yaml-workflows-BjrMQLTK.js.map → yaml-workflows-Df8u3lgx.js.map} +1 -1
  219. package/dashboard/dist/index.html +3 -3
  220. package/docs/api/http/escalations.md +6 -6
  221. package/docs/api/http/roles.md +6 -0
  222. package/docs/api/http/workflows.md +2 -1
  223. package/docs/api/mcp/admin.md +15 -7
  224. package/docs/api/sdk/escalations.md +5 -3
  225. package/docs/api/sdk/roles.md +7 -1
  226. package/docs/api/sdk/workflows.md +3 -2
  227. package/docs/architecture.md +2 -2
  228. package/docs/dashboard.md +11 -9
  229. package/docs/data.md +2 -0
  230. package/docs/iam.md +3 -3
  231. package/docs/operations.md +16 -3
  232. package/docs/workflows.md +7 -5
  233. package/package.json +2 -2
  234. package/dashboard/dist/assets/OperationsPage-BCr21p8I.js +0 -2
  235. package/dashboard/dist/assets/OperationsPage-BCr21p8I.js.map +0 -1
  236. package/dashboard/dist/assets/RoleDetailPage-DS37tJhq.js +0 -11
  237. package/dashboard/dist/assets/RoleDetailPage-DS37tJhq.js.map +0 -1
  238. package/dashboard/dist/assets/WorkflowPill-IDjTRfQ8.js.map +0 -1
  239. package/dashboard/dist/assets/index-D0-8byNu.js +0 -6
  240. package/dashboard/dist/assets/index-D0-8byNu.js.map +0 -1
  241. package/dashboard/dist/assets/index-TiKh2Ctj.js +0 -9
  242. package/dashboard/dist/assets/index-TiKh2Ctj.js.map +0 -1
  243. package/dashboard/dist/assets/roles-CFD2eYap.js.map +0 -1
  244. package/dashboard/dist/assets/workflows-CkPv7xk-.js.map +0 -1
@@ -45,15 +45,32 @@ export declare function searchEscalationsQuery(orderBy: string): string;
45
45
  */
46
46
  export declare const RESOLVE_BY_METADATA_ATOMIC = "WITH target AS MATERIALIZED (\n SELECT *\n FROM public.hmsh_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n $5::text[] IS NULL\n OR role = ANY($5)\n OR (role = ANY($6::text[]) AND assigned_to = $2)\n )\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE\n),\nclaimed AS (\n UPDATE public.hmsh_escalations e\n SET assigned_to = COALESCE(e.assigned_to, $2),\n claimed_at = COALESCE(e.claimed_at, NOW()),\n assigned_until = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.assigned_until\n ELSE NOW() + INTERVAL '5 minutes' END,\n claim_expires_at = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.claim_expires_at\n ELSE NOW() + INTERVAL '5 minutes' END,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END,\n updated_at = NOW()\n FROM target\n WHERE e.id = target.id\n AND target.signal_key IS NULL\n RETURNING e.*\n),\nresolved AS (\n UPDATE public.hmsh_escalations e\n SET status = 'resolved',\n resolved_at = NOW(),\n resolver_payload = $3,\n updated_at = NOW()\n FROM claimed\n WHERE e.id = claimed.id\n AND (claimed.metadata->>'signal_id') IS NULL\n RETURNING e.*\n)\nSELECT\n resolved.*,\n target.id AS target_id,\n target.metadata->>'signal_id' AS signal_id,\n target.signal_key AS signal_key,\n target.workflow_id AS target_workflow_id,\n target.workflow_type AS target_workflow_type,\n target.task_queue AS target_task_queue,\n (target.assigned_to IS NOT NULL\n AND target.assigned_until IS NOT NULL\n AND target.assigned_until > NOW()) AS signal_already_claimed,\n CASE WHEN resolved.id IS NOT NULL THEN 'resolved' ELSE 'signal_required' END AS outcome\nFROM target\nLEFT JOIN resolved ON resolved.id = target.id";
47
47
  /**
48
- * Live counts — pending, active claims, and past-SLA (in_arrears) per role.
48
+ * Live counts — pending, active claims, and priority (past-threshold) per role.
49
49
  *
50
50
  * $1 TEXT[] — role filter (NULL = all roles / superadmin).
51
51
  *
52
52
  * Hits idx_hmsh_esc_pending_role_created (role, created_at DESC) WHERE
53
53
  * status='pending'. The pending working set is bounded by real backlog depth,
54
54
  * so this stays cheap as historical volume grows — safe on the hot refresh path.
55
+ *
56
+ * priority_count is the Pace Board rebalance signal: pending AND unclaimed
57
+ * items older than the role's threshold. One signal, two per-role dials with
58
+ * fallbacks so it works from sla_minutes alone:
59
+ *
60
+ * age origin — priority_facet metadata key (an ISO 8601 UTC timestamp, e.g.
61
+ * the order's authorized date) when set, else created_at.
62
+ * threshold — priority_threshold_minutes when set, else sla_minutes.
63
+ *
64
+ * Claimed items are excluded — they are already in someone's hands; the count
65
+ * is what the floor must still pull forward. The GIN metadata index only
66
+ * serves containment, not age comparisons, so the facet read rides the same
67
+ * bounded pending scan as the other counts. The cast is guarded by
68
+ * pg_input_is_valid inside a CASE (Postgres does not promise AND evaluation
69
+ * order) so one malformed metadata value can never break the stats query;
70
+ * with a facet configured, items missing the key or holding an unparseable
71
+ * value do not count (NULL age never passes the comparison).
55
72
  */
56
- export declare const STATION_LIVE_COUNTS_SQL = "\nWITH role_targets AS (\n SELECT role, sla_minutes\n FROM lt_roles\n WHERE ($1::text[] IS NULL OR role = ANY($1::text[]))\n),\nlive_counts AS (\n SELECT\n e.role,\n COUNT(*) AS pending,\n COUNT(*) FILTER (WHERE e.assigned_to IS NOT NULL AND e.assigned_until > NOW()) AS claimed,\n COUNT(*) FILTER (\n WHERE rt.sla_minutes IS NOT NULL\n AND e.created_at < NOW() - (rt.sla_minutes * INTERVAL '1 minute')\n ) AS in_arrears\n FROM hmsh_escalations e\n JOIN role_targets rt ON rt.role = e.role\n WHERE e.status = 'pending'\n GROUP BY e.role\n)\nSELECT\n rt.role,\n COALESCE(lc.pending, 0) AS pending,\n COALESCE(lc.claimed, 0) AS claimed,\n COALESCE(lc.in_arrears, 0) AS in_arrears\nFROM role_targets rt\nLEFT JOIN live_counts lc ON lc.role = rt.role\nORDER BY rt.role\n";
73
+ export declare const STATION_LIVE_COUNTS_SQL = "\nWITH role_targets AS (\n SELECT role, sla_minutes, priority_threshold_minutes, priority_facet\n FROM lt_roles\n WHERE ($1::text[] IS NULL OR role = ANY($1::text[]))\n),\nlive_counts AS (\n SELECT\n e.role,\n COUNT(*) AS pending,\n COUNT(*) FILTER (WHERE e.assigned_to IS NOT NULL AND e.assigned_until > NOW()) AS claimed,\n COUNT(*) FILTER (\n WHERE COALESCE(rt.priority_threshold_minutes, rt.sla_minutes) IS NOT NULL\n AND (e.assigned_to IS NULL OR e.assigned_until IS NULL OR e.assigned_until <= NOW())\n AND CASE\n WHEN rt.priority_facet IS NULL THEN e.created_at\n WHEN pg_input_is_valid(e.metadata->>rt.priority_facet, 'timestamptz')\n THEN (e.metadata->>rt.priority_facet)::timestamptz\n ELSE NULL\n END < NOW() - (COALESCE(rt.priority_threshold_minutes, rt.sla_minutes) * INTERVAL '1 minute')\n ) AS priority_count\n FROM hmsh_escalations e\n JOIN role_targets rt ON rt.role = e.role\n WHERE e.status = 'pending'\n GROUP BY e.role\n)\nSELECT\n rt.role,\n COALESCE(lc.pending, 0) AS pending,\n COALESCE(lc.claimed, 0) AS claimed,\n COALESCE(lc.priority_count, 0) AS priority_count\nFROM role_targets rt\nLEFT JOIN live_counts lc ON lc.role = rt.role\nORDER BY rt.role\n";
57
74
  /**
58
75
  * Period metrics — resolved count, throughput efficiency, and P99/P50/avg/max
59
76
  * latency for wait (queue time) and work (processing) per role.
@@ -192,7 +192,7 @@ LEFT JOIN resolved ON resolved.id = target.id`;
192
192
  // path is wasteful: percentile aggregates sort every qualifying resolved row,
193
193
  // while the live counts are cheap and bounded. So the two halves are separated:
194
194
  //
195
- // STATION_LIVE_COUNTS_SQL — pending / claimed / in_arrears. Cheap, always
195
+ // STATION_LIVE_COUNTS_SQL — pending / claimed / priority_count. Cheap, always
196
196
  // run fresh. Scans only pending rows (backlog is
197
197
  // bounded no matter how much history accrues).
198
198
  // STATION_PERIOD_METRICS_SQL — resolved / throughput / latency percentiles.
@@ -204,17 +204,34 @@ LEFT JOIN resolved ON resolved.id = target.id`;
204
204
  // and the service merges them by role into one StationMetric per station.
205
205
  // ---------------------------------------------------------------------------
206
206
  /**
207
- * Live counts — pending, active claims, and past-SLA (in_arrears) per role.
207
+ * Live counts — pending, active claims, and priority (past-threshold) per role.
208
208
  *
209
209
  * $1 TEXT[] — role filter (NULL = all roles / superadmin).
210
210
  *
211
211
  * Hits idx_hmsh_esc_pending_role_created (role, created_at DESC) WHERE
212
212
  * status='pending'. The pending working set is bounded by real backlog depth,
213
213
  * so this stays cheap as historical volume grows — safe on the hot refresh path.
214
+ *
215
+ * priority_count is the Pace Board rebalance signal: pending AND unclaimed
216
+ * items older than the role's threshold. One signal, two per-role dials with
217
+ * fallbacks so it works from sla_minutes alone:
218
+ *
219
+ * age origin — priority_facet metadata key (an ISO 8601 UTC timestamp, e.g.
220
+ * the order's authorized date) when set, else created_at.
221
+ * threshold — priority_threshold_minutes when set, else sla_minutes.
222
+ *
223
+ * Claimed items are excluded — they are already in someone's hands; the count
224
+ * is what the floor must still pull forward. The GIN metadata index only
225
+ * serves containment, not age comparisons, so the facet read rides the same
226
+ * bounded pending scan as the other counts. The cast is guarded by
227
+ * pg_input_is_valid inside a CASE (Postgres does not promise AND evaluation
228
+ * order) so one malformed metadata value can never break the stats query;
229
+ * with a facet configured, items missing the key or holding an unparseable
230
+ * value do not count (NULL age never passes the comparison).
214
231
  */
215
232
  exports.STATION_LIVE_COUNTS_SQL = `
216
233
  WITH role_targets AS (
217
- SELECT role, sla_minutes
234
+ SELECT role, sla_minutes, priority_threshold_minutes, priority_facet
218
235
  FROM lt_roles
219
236
  WHERE ($1::text[] IS NULL OR role = ANY($1::text[]))
220
237
  ),
@@ -224,9 +241,15 @@ live_counts AS (
224
241
  COUNT(*) AS pending,
225
242
  COUNT(*) FILTER (WHERE e.assigned_to IS NOT NULL AND e.assigned_until > NOW()) AS claimed,
226
243
  COUNT(*) FILTER (
227
- WHERE rt.sla_minutes IS NOT NULL
228
- AND e.created_at < NOW() - (rt.sla_minutes * INTERVAL '1 minute')
229
- ) AS in_arrears
244
+ WHERE COALESCE(rt.priority_threshold_minutes, rt.sla_minutes) IS NOT NULL
245
+ AND (e.assigned_to IS NULL OR e.assigned_until IS NULL OR e.assigned_until <= NOW())
246
+ AND CASE
247
+ WHEN rt.priority_facet IS NULL THEN e.created_at
248
+ WHEN pg_input_is_valid(e.metadata->>rt.priority_facet, 'timestamptz')
249
+ THEN (e.metadata->>rt.priority_facet)::timestamptz
250
+ ELSE NULL
251
+ END < NOW() - (COALESCE(rt.priority_threshold_minutes, rt.sla_minutes) * INTERVAL '1 minute')
252
+ ) AS priority_count
230
253
  FROM hmsh_escalations e
231
254
  JOIN role_targets rt ON rt.role = e.role
232
255
  WHERE e.status = 'pending'
@@ -234,9 +257,9 @@ live_counts AS (
234
257
  )
235
258
  SELECT
236
259
  rt.role,
237
- COALESCE(lc.pending, 0) AS pending,
238
- COALESCE(lc.claimed, 0) AS claimed,
239
- COALESCE(lc.in_arrears, 0) AS in_arrears
260
+ COALESCE(lc.pending, 0) AS pending,
261
+ COALESCE(lc.claimed, 0) AS claimed,
262
+ COALESCE(lc.priority_count, 0) AS priority_count
240
263
  FROM role_targets rt
241
264
  LEFT JOIN live_counts lc ON lc.role = rt.role
242
265
  ORDER BY rt.role
@@ -50,7 +50,13 @@ export interface StationMetric {
50
50
  pending: number;
51
51
  claimed: number;
52
52
  resolved: number;
53
- in_arrears: number;
53
+ /**
54
+ * Pending, unclaimed items past the role's threshold — the Pace Board
55
+ * rebalance signal. Age is measured from the role's priority_facet metadata
56
+ * timestamp (created_at when unset) against priority_threshold_minutes
57
+ * (sla_minutes when unset). 0 when neither threshold is configured.
58
+ */
59
+ priority_count: number;
54
60
  /** resolved_in_period / (target_per_hour × period_hours) × 100. Null when no target set. */
55
61
  throughput_pct: number | null;
56
62
  wait: StationMetricPeriod;
@@ -139,6 +139,8 @@ async function updateRoleMetadata(role, input) {
139
139
  provided('sla_minutes'), input.sla_minutes ?? null,
140
140
  provided('target_per_hour'), input.target_per_hour ?? null,
141
141
  provided('worker_count'), input.worker_count ?? null,
142
+ provided('priority_threshold_minutes'), input.priority_threshold_minutes ?? null,
143
+ provided('priority_facet'), input.priority_facet ?? null,
142
144
  input.change_summary ?? null,
143
145
  provided('upstream_roles'), upstreams,
144
146
  ]);
@@ -27,15 +27,15 @@ export declare const DELETE_ROLE = "\n DELETE FROM lt_roles WHERE role = $1";
27
27
  * evaluated against the pre-update row), current_schema_version advances and
28
28
  * the post-update schema pair is snapshotted into lt_role_schemas. A no-change
29
29
  * save leaves the version alone and the snapshot INSERT conflicts away.
30
- * $22 = optional change summary recorded on the snapshot.
30
+ * $26 = optional change summary recorded on the snapshot.
31
31
  *
32
- * Upstream inputs ($23 = provided sentinel, $24 = replacement set) sync in the
32
+ * Upstream inputs ($27 = provided sentinel, $28 = replacement set) sync in the
33
33
  * same statement with replace semantics. The two CTEs deliberately avoid
34
34
  * touching the same row: the DELETE only removes rows leaving the set, and the
35
35
  * INSERT's ON CONFLICT DO NOTHING skips rows that stay (delete+insert of the
36
36
  * SAME key in one statement would silently drop it — CTEs share a snapshot).
37
37
  */
38
- export declare const UPDATE_ROLE_METADATA = "\n WITH updated AS (\n UPDATE lt_roles SET\n title = CASE WHEN $2::boolean THEN $3 ELSE title END,\n description = CASE WHEN $4::boolean THEN $5 ELSE description END,\n form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,\n metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,\n properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,\n ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,\n parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,\n sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,\n target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,\n worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END,\n current_schema_version = CASE\n WHEN ($6::boolean AND $7::jsonb IS DISTINCT FROM form_schema)\n OR ($8::boolean AND $9::jsonb IS DISTINCT FROM metadata_schema)\n THEN COALESCE(current_schema_version, 0) + 1\n ELSE current_schema_version END\n WHERE role = $1\n RETURNING\n role, title, description, form_schema, metadata_schema, properties,\n ops_visible, parent_role, sla_minutes, target_per_hour, worker_count,\n current_schema_version\n ), snapshot AS (\n INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)\n SELECT role, current_schema_version, form_schema, metadata_schema, $22\n FROM updated\n WHERE ($6::boolean OR $8::boolean) AND current_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), upstream_prune AS (\n DELETE FROM lt_role_upstreams\n WHERE $23::boolean AND role = $1 AND upstream_role <> ALL($24::text[])\n ), upstream_add AS (\n INSERT INTO lt_role_upstreams (role, upstream_role)\n SELECT $1, u FROM unnest($24::text[]) AS u\n WHERE $23::boolean\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM updated";
38
+ export declare const UPDATE_ROLE_METADATA = "\n WITH updated AS (\n UPDATE lt_roles SET\n title = CASE WHEN $2::boolean THEN $3 ELSE title END,\n description = CASE WHEN $4::boolean THEN $5 ELSE description END,\n form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,\n metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,\n properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,\n ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,\n parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,\n sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,\n target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,\n worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END,\n priority_threshold_minutes\n = CASE WHEN $22::boolean THEN $23::numeric ELSE priority_threshold_minutes END,\n priority_facet = CASE WHEN $24::boolean THEN $25 ELSE priority_facet END,\n current_schema_version = CASE\n WHEN ($6::boolean AND $7::jsonb IS DISTINCT FROM form_schema)\n OR ($8::boolean AND $9::jsonb IS DISTINCT FROM metadata_schema)\n THEN COALESCE(current_schema_version, 0) + 1\n ELSE current_schema_version END\n WHERE role = $1\n RETURNING\n role, title, description, form_schema, metadata_schema, properties,\n ops_visible, parent_role, sla_minutes, target_per_hour, worker_count,\n priority_threshold_minutes, priority_facet,\n current_schema_version\n ), snapshot AS (\n INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)\n SELECT role, current_schema_version, form_schema, metadata_schema, $26\n FROM updated\n WHERE ($6::boolean OR $8::boolean) AND current_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), upstream_prune AS (\n DELETE FROM lt_role_upstreams\n WHERE $27::boolean AND role = $1 AND upstream_role <> ALL($28::text[])\n ), upstream_add AS (\n INSERT INTO lt_role_upstreams (role, upstream_role)\n SELECT $1, u FROM unnest($28::text[]) AS u\n WHERE $27::boolean\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM updated";
39
39
  export declare const GET_ROLE_FORM_SCHEMA = "\n SELECT form_schema FROM lt_roles WHERE role = $1";
40
40
  export declare const GET_ROLE_METADATA_SCHEMA = "\n SELECT metadata_schema FROM lt_roles WHERE role = $1";
41
41
  export declare const GET_ROLE_UPSTREAMS = "\n SELECT upstream_role FROM lt_role_upstreams WHERE role = $1 ORDER BY upstream_role";
@@ -46,7 +46,7 @@ export declare const GET_ROLE_SCHEMA_VERSION = "\n SELECT s.role, s.version, s.
46
46
  * versioned its schema still answers, with version NULL).
47
47
  */
48
48
  export declare const GET_ROLE_SCHEMA_CURRENT = "\n SELECT r.role, r.current_schema_version AS version, r.form_schema,\n r.metadata_schema, s.change_summary, s.created_at,\n r.current_schema_version AS latest_version\n FROM lt_roles r\n LEFT JOIN lt_role_schemas s\n ON s.role = r.role AND s.version = r.current_schema_version\n WHERE r.role = $1";
49
- export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n ),\n upstreams AS (\n SELECT role, array_agg(upstream_role ORDER BY upstream_role) AS ups\n FROM lt_role_upstreams\n GROUP BY role\n )\n SELECT\n r.role,\n r.title,\n r.description,\n r.form_schema,\n r.metadata_schema,\n r.properties,\n r.ops_visible,\n r.parent_role,\n r.sla_minutes,\n r.target_per_hour,\n r.worker_count,\n r.current_schema_version,\n COALESCE(up.ups, '{}') AS upstream_roles,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n LEFT JOIN upstreams up ON up.role = r.role\n ORDER BY r.role";
49
+ export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n ),\n upstreams AS (\n SELECT role, array_agg(upstream_role ORDER BY upstream_role) AS ups\n FROM lt_role_upstreams\n GROUP BY role\n )\n SELECT\n r.role,\n r.title,\n r.description,\n r.form_schema,\n r.metadata_schema,\n r.properties,\n r.ops_visible,\n r.parent_role,\n r.sla_minutes,\n r.target_per_hour,\n r.worker_count,\n r.priority_threshold_minutes,\n r.priority_facet,\n r.current_schema_version,\n COALESCE(up.ups, '{}') AS upstream_roles,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n LEFT JOIN upstreams up ON up.role = r.role\n ORDER BY r.role";
50
50
  export declare const COUNT_USER_ROLE_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_user_roles WHERE role = $1";
51
51
  export declare const COUNT_CHAIN_REFS = "\n SELECT COUNT(*)::int AS cnt\n FROM lt_config_role_escalations\n WHERE source_role = $1 OR target_role = $1";
52
52
  export declare const COUNT_WORKFLOW_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_config_roles WHERE role = $1";
@@ -61,9 +61,9 @@ exports.DELETE_ROLE = `
61
61
  * evaluated against the pre-update row), current_schema_version advances and
62
62
  * the post-update schema pair is snapshotted into lt_role_schemas. A no-change
63
63
  * save leaves the version alone and the snapshot INSERT conflicts away.
64
- * $22 = optional change summary recorded on the snapshot.
64
+ * $26 = optional change summary recorded on the snapshot.
65
65
  *
66
- * Upstream inputs ($23 = provided sentinel, $24 = replacement set) sync in the
66
+ * Upstream inputs ($27 = provided sentinel, $28 = replacement set) sync in the
67
67
  * same statement with replace semantics. The two CTEs deliberately avoid
68
68
  * touching the same row: the DELETE only removes rows leaving the set, and the
69
69
  * INSERT's ON CONFLICT DO NOTHING skips rows that stay (delete+insert of the
@@ -82,6 +82,9 @@ exports.UPDATE_ROLE_METADATA = `
82
82
  sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,
83
83
  target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,
84
84
  worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END,
85
+ priority_threshold_minutes
86
+ = CASE WHEN $22::boolean THEN $23::numeric ELSE priority_threshold_minutes END,
87
+ priority_facet = CASE WHEN $24::boolean THEN $25 ELSE priority_facet END,
85
88
  current_schema_version = CASE
86
89
  WHEN ($6::boolean AND $7::jsonb IS DISTINCT FROM form_schema)
87
90
  OR ($8::boolean AND $9::jsonb IS DISTINCT FROM metadata_schema)
@@ -91,20 +94,21 @@ exports.UPDATE_ROLE_METADATA = `
91
94
  RETURNING
92
95
  role, title, description, form_schema, metadata_schema, properties,
93
96
  ops_visible, parent_role, sla_minutes, target_per_hour, worker_count,
97
+ priority_threshold_minutes, priority_facet,
94
98
  current_schema_version
95
99
  ), snapshot AS (
96
100
  INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)
97
- SELECT role, current_schema_version, form_schema, metadata_schema, $22
101
+ SELECT role, current_schema_version, form_schema, metadata_schema, $26
98
102
  FROM updated
99
103
  WHERE ($6::boolean OR $8::boolean) AND current_schema_version IS NOT NULL
100
104
  ON CONFLICT (role, version) DO NOTHING
101
105
  ), upstream_prune AS (
102
106
  DELETE FROM lt_role_upstreams
103
- WHERE $23::boolean AND role = $1 AND upstream_role <> ALL($24::text[])
107
+ WHERE $27::boolean AND role = $1 AND upstream_role <> ALL($28::text[])
104
108
  ), upstream_add AS (
105
109
  INSERT INTO lt_role_upstreams (role, upstream_role)
106
- SELECT $1, u FROM unnest($24::text[]) AS u
107
- WHERE $23::boolean
110
+ SELECT $1, u FROM unnest($28::text[]) AS u
111
+ WHERE $27::boolean
108
112
  ON CONFLICT DO NOTHING
109
113
  )
110
114
  SELECT * FROM updated`;
@@ -184,6 +188,8 @@ exports.LIST_ROLES_WITH_DETAILS = `
184
188
  r.sla_minutes,
185
189
  r.target_per_hour,
186
190
  r.worker_count,
191
+ r.priority_threshold_minutes,
192
+ r.priority_facet,
187
193
  r.current_schema_version,
188
194
  COALESCE(up.ups, '{}') AS upstream_roles,
189
195
  COALESCE(uc.cnt, 0) AS user_count,
@@ -25,6 +25,18 @@ export interface RoleDetail {
25
25
  target_per_hour: number | null;
26
26
  /** Capacity at this station (people or machines). Part of the ops triangle. */
27
27
  worker_count: number | null;
28
+ /**
29
+ * Max age (minutes) before a pending, unclaimed escalation counts toward the
30
+ * Pace Board priority count. Falls back to sla_minutes when null.
31
+ */
32
+ priority_threshold_minutes: number | null;
33
+ /**
34
+ * lt_escalations.metadata key holding the age origin for the priority count
35
+ * as an ISO 8601 UTC timestamp (e.g. the order's authorized date). Falls
36
+ * back to created_at when null. When set, items missing the key or holding
37
+ * an unparseable value are not counted.
38
+ */
39
+ priority_facet: string | null;
28
40
  /**
29
41
  * Version of the live form_schema/metadata_schema pair. Advances whenever a
30
42
  * schema field changes; each version is snapshotted in lt_role_schemas so
@@ -74,6 +86,8 @@ export interface UpdateRoleInput {
74
86
  sla_minutes?: number | null;
75
87
  target_per_hour?: number | null;
76
88
  worker_count?: number | null;
89
+ priority_threshold_minutes?: number | null;
90
+ priority_facet?: string | null;
77
91
  /**
78
92
  * Replace the upstream-input set (omitted = preserve; null or [] = clear).
79
93
  * Every entry must name an existing role other than this one.
@@ -173,6 +173,7 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
173
173
  workflow_type: workflowType,
174
174
  task_queue: w.taskQueue,
175
175
  invocable: c.invocable ?? false,
176
+ certified: c.certified,
176
177
  default_role: c.defaultRole ?? 'reviewer',
177
178
  description: c.description ?? null,
178
179
  roles: c.roles ?? [],
@@ -234,6 +234,7 @@ export declare const listWorkflowConfigsSchema: z.ZodObject<{}, "strip", z.ZodTy
234
234
  export declare const upsertWorkflowConfigSchema: z.ZodObject<{
235
235
  workflow_type: z.ZodString;
236
236
  invocable: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
237
+ certified: z.ZodOptional<z.ZodBoolean>;
237
238
  task_queue: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
238
239
  default_role: z.ZodDefault<z.ZodOptional<z.ZodString>>;
239
240
  description: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
@@ -259,8 +260,10 @@ export declare const upsertWorkflowConfigSchema: z.ZodObject<{
259
260
  resolver_schema: Record<string, any> | null;
260
261
  cron_schedule: string | null;
261
262
  execute_as: string | null;
263
+ certified?: boolean | undefined;
262
264
  }, {
263
265
  workflow_type: string;
266
+ certified?: boolean | undefined;
264
267
  invocable?: boolean | undefined;
265
268
  task_queue?: string | null | undefined;
266
269
  default_role?: string | undefined;
@@ -562,6 +565,8 @@ export declare const updateRoleSchema: z.ZodObject<{
562
565
  sla_minutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
563
566
  target_per_hour: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
564
567
  worker_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
568
+ priority_threshold_minutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
569
+ priority_facet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
565
570
  upstream_roles: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
566
571
  change_summary: z.ZodOptional<z.ZodString>;
567
572
  }, "strip", z.ZodTypeAny, {
@@ -576,6 +581,8 @@ export declare const updateRoleSchema: z.ZodObject<{
576
581
  sla_minutes?: number | null | undefined;
577
582
  target_per_hour?: number | null | undefined;
578
583
  worker_count?: number | null | undefined;
584
+ priority_threshold_minutes?: number | null | undefined;
585
+ priority_facet?: string | null | undefined;
579
586
  upstream_roles?: string[] | null | undefined;
580
587
  change_summary?: string | undefined;
581
588
  }, {
@@ -590,6 +597,8 @@ export declare const updateRoleSchema: z.ZodObject<{
590
597
  sla_minutes?: number | null | undefined;
591
598
  target_per_hour?: number | null | undefined;
592
599
  worker_count?: number | null | undefined;
600
+ priority_threshold_minutes?: number | null | undefined;
601
+ priority_facet?: string | null | undefined;
593
602
  upstream_roles?: string[] | null | undefined;
594
603
  change_summary?: string | undefined;
595
604
  }>;
@@ -14,6 +14,7 @@ exports.claimByFacetsSchema = exports.claimGroupsSchema = exports.searchByFacets
14
14
  * deep-instantiation errors in the registerTool() generic.
15
15
  */
16
16
  const zod_1 = require("zod");
17
+ const facet_sql_1 = require("../../../services/escalation/facet-sql");
17
18
  // ── tasks (routes/tasks.ts) ─────────────────────────────────────────────────
18
19
  exports.findTasksSchema = zod_1.z.object({
19
20
  status: zod_1.z.string().optional().describe('Filter: pending, completed, etc.'),
@@ -102,6 +103,8 @@ exports.listWorkflowConfigsSchema = zod_1.z.object({});
102
103
  exports.upsertWorkflowConfigSchema = zod_1.z.object({
103
104
  workflow_type: zod_1.z.string().describe('Workflow function name'),
104
105
  invocable: zod_1.z.boolean().optional().default(false),
106
+ certified: zod_1.z.boolean().optional()
107
+ .describe('Explicit HITL certification (interceptor treatment). Omitted → derived from roles/consumes presence.'),
105
108
  task_queue: zod_1.z.string().nullable().optional().default(null),
106
109
  default_role: zod_1.z.string().optional().default('reviewer'),
107
110
  description: zod_1.z.string().nullable().optional().default(null),
@@ -116,7 +119,7 @@ exports.upsertWorkflowConfigSchema = zod_1.z.object({
116
119
  cron_schedule: zod_1.z.string().nullable().optional().default(null),
117
120
  });
118
121
  exports.deleteWorkflowConfigSchema = zod_1.z.object({
119
- workflow_type: zod_1.z.string().describe('Workflow type to de-certify'),
122
+ workflow_type: zod_1.z.string().describe('Workflow type to unregister (deletes the registration row)'),
120
123
  });
121
124
  // ── workflows (routes/workflows/invocation.ts + discovery.ts) ───────────────
122
125
  exports.listDiscoveredWorkflowsSchema = zod_1.z.object({
@@ -242,6 +245,8 @@ exports.updateRoleSchema = zod_1.z.object({
242
245
  sla_minutes: zod_1.z.number().nullable().optional().describe('Target resolution time in minutes. One of the capacity settings: target_per_hour = worker_count / (sla_minutes / 60)'),
243
246
  target_per_hour: zod_1.z.number().nullable().optional().describe('Intended throughput (items resolved per hour). Drives the station pace baseline on the Operations view.'),
244
247
  worker_count: zod_1.z.number().nullable().optional().describe('Capacity at this station (staff or machine count). One of the capacity settings.'),
248
+ priority_threshold_minutes: zod_1.z.number().min(0).nullable().optional().describe('Max age in minutes before a pending unclaimed escalation counts toward the Pace Board priority count. Falls back to sla_minutes when null.'),
249
+ priority_facet: zod_1.z.string().regex(facet_sql_1.FACET_KEY).nullable().optional().describe('lt_escalations.metadata key holding the age origin for the priority count as an ISO 8601 UTC timestamp (e.g. authorized_at). Falls back to created_at when null. When set, items missing the key or holding an unparseable value are not counted.'),
245
250
  upstream_roles: zod_1.z.array(zod_1.z.string()).nullable().optional().describe('Replace the set of roles this station draws input from across other sequences (parent_role stays the single prior step in its own sequence). Omitted = preserve; null or [] = clear.'),
246
251
  change_summary: zod_1.z.string().optional().describe('Recorded on the schema version snapshot when this update changes form_schema or metadata_schema'),
247
252
  });
@@ -196,7 +196,8 @@ function registerUserTools(server) {
196
196
  description: 'Update role metadata with PATCH semantics — omitted fields keep their ' +
197
197
  'values. Covers display name, description, form/metadata schemas, the ' +
198
198
  'free properties bag, ops_visible flag, parent role, and the typed ' +
199
- 'operational targets (sla_minutes, target_per_hour, worker_count).',
199
+ 'operational targets (sla_minutes, target_per_hour, worker_count, ' +
200
+ 'priority_threshold_minutes, priority_facet).',
200
201
  inputSchema: schemas_1.updateRoleSchema,
201
202
  }, async (args) => {
202
203
  const updated = await roleService.updateRoleMetadata(args.role, {
@@ -210,6 +211,8 @@ function registerUserTools(server) {
210
211
  sla_minutes: args.sla_minutes,
211
212
  target_per_hour: args.target_per_hour,
212
213
  worker_count: args.worker_count,
214
+ priority_threshold_minutes: args.priority_threshold_minutes,
215
+ priority_facet: args.priority_facet,
213
216
  upstream_roles: args.upstream_roles,
214
217
  change_summary: args.change_summary,
215
218
  });
@@ -75,6 +75,7 @@ function registerWorkflowConfigTools(server) {
75
75
  const config = await configService.upsertWorkflowConfig({
76
76
  workflow_type: args.workflow_type,
77
77
  invocable: args.invocable,
78
+ certified: args.certified,
78
79
  task_queue: args.task_queue,
79
80
  default_role: args.default_role,
80
81
  description: args.description,