@hotmeshio/long-tail 0.10.13 → 0.11.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 (373) hide show
  1. package/README.md +2 -4
  2. package/build/api/escalations/analytics.d.ts +6 -0
  3. package/build/api/escalations/analytics.js +123 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +4 -1
  6. package/build/api/escalations/metadata.js +1 -1
  7. package/build/api/escalations/resolve.js +4 -4
  8. package/build/api/roles.d.ts +4 -0
  9. package/build/api/roles.js +8 -0
  10. package/build/api/scan-codes/choice.d.ts +11 -0
  11. package/build/api/scan-codes/choice.js +136 -0
  12. package/build/api/scan-codes/context.d.ts +24 -0
  13. package/build/api/scan-codes/context.js +86 -0
  14. package/build/api/scan-codes/execute.d.ts +1 -0
  15. package/build/api/scan-codes/execute.js +49 -244
  16. package/build/api/scan-codes/identity.d.ts +18 -0
  17. package/build/api/scan-codes/identity.js +116 -0
  18. package/build/api/scan-codes/index.d.ts +2 -0
  19. package/build/api/scan-codes/index.js +6 -1
  20. package/build/api/scan-codes/locate.d.ts +14 -0
  21. package/build/api/scan-codes/locate.js +127 -0
  22. package/build/api/scan-codes/present.d.ts +9 -0
  23. package/build/api/scan-codes/present.js +59 -0
  24. package/build/api/scan-codes/verbs.d.ts +15 -0
  25. package/build/api/scan-codes/verbs.js +205 -0
  26. package/build/bin/ltc.js +33 -0
  27. package/build/lib/cli/commands/escalations.d.ts +31 -0
  28. package/build/lib/cli/commands/escalations.js +88 -0
  29. package/build/lib/db/schemas/028_role_entity_facet.sql +18 -0
  30. package/build/lib/db/schemas/029_scan_scheme_kind.sql +31 -0
  31. package/build/modules/config.d.ts +5 -0
  32. package/build/modules/config.js +12 -0
  33. package/build/routes/escalations/acting.d.ts +12 -0
  34. package/build/routes/escalations/acting.js +25 -0
  35. package/build/routes/escalations/analytics.d.ts +8 -0
  36. package/build/routes/escalations/analytics.js +63 -0
  37. package/build/routes/escalations/index.js +3 -0
  38. package/build/routes/escalations/resolve.js +8 -1
  39. package/build/routes/escalations/single.js +13 -4
  40. package/build/routes/roles.js +1 -1
  41. package/build/routes/scan-codes.js +28 -2
  42. package/build/scripts/ortho-populate.js +14 -0
  43. package/build/scripts/printer-cycle.d.ts +25 -0
  44. package/build/scripts/printer-cycle.js +169 -0
  45. package/build/scripts/twin-farm.js +19 -5
  46. package/build/sdk/index.d.ts +2 -0
  47. package/build/sdk/index.js +3 -0
  48. package/build/services/escalation/aggregate-sql.d.ts +36 -0
  49. package/build/services/escalation/aggregate-sql.js +253 -0
  50. package/build/services/escalation/aggregate-validate.d.ts +57 -0
  51. package/build/services/escalation/aggregate-validate.js +218 -0
  52. package/build/services/escalation/aggregates.d.ts +26 -0
  53. package/build/services/escalation/aggregates.js +204 -0
  54. package/build/services/escalation/client.js +57 -21
  55. package/build/services/escalation/facet-sql.js +17 -0
  56. package/build/services/escalation/index.d.ts +2 -0
  57. package/build/services/escalation/index.js +8 -1
  58. package/build/services/escalation/metrics-cache.d.ts +18 -0
  59. package/build/services/escalation/metrics-cache.js +47 -1
  60. package/build/services/escalation/queries.js +2 -0
  61. package/build/services/escalation/resolver-validation.d.ts +1 -1
  62. package/build/services/escalation/resolver-validation.js +12 -5
  63. package/build/services/escalation/submit-guard.d.ts +29 -0
  64. package/build/services/escalation/submit-guard.js +57 -0
  65. package/build/services/iam/acting-identity.d.ts +16 -0
  66. package/build/services/iam/acting-identity.js +60 -0
  67. package/build/services/role/index.js +2 -0
  68. package/build/services/role/sql.d.ts +10 -2
  69. package/build/services/role/sql.js +14 -1
  70. package/build/services/role/types.d.ts +16 -0
  71. package/build/services/scan-code/read.js +4 -0
  72. package/build/services/scan-code/sql.d.ts +4 -4
  73. package/build/services/scan-code/sql.js +14 -8
  74. package/build/services/scan-code/validate.d.ts +2 -0
  75. package/build/services/scan-code/validate.js +86 -0
  76. package/build/services/scan-code/write.d.ts +4 -0
  77. package/build/services/scan-code/write.js +16 -2
  78. package/build/services/user/crud.d.ts +6 -0
  79. package/build/services/user/crud.js +16 -0
  80. package/build/services/user/index.d.ts +1 -1
  81. package/build/services/user/index.js +2 -1
  82. package/build/services/user/sql.d.ts +8 -0
  83. package/build/services/user/sql.js +9 -1
  84. package/build/shared/form-validation/index.d.ts +4 -0
  85. package/build/shared/form-validation/index.js +4 -0
  86. package/build/shared/form-validation/x-lt-labels.d.ts +28 -0
  87. package/build/shared/form-validation/x-lt-labels.js +42 -0
  88. package/build/shared/form-validation/x-lt-query.d.ts +56 -0
  89. package/build/shared/form-validation/x-lt-query.js +49 -0
  90. package/build/shared/form-validation/x-lt-submit-guard.d.ts +46 -0
  91. package/build/shared/form-validation/x-lt-submit-guard.js +25 -0
  92. package/build/shared/form-validation/x-lt-submit-on-claim.d.ts +22 -0
  93. package/build/shared/form-validation/x-lt-submit-on-claim.js +28 -0
  94. package/build/system/mcp-servers/admin/escalations.js +34 -0
  95. package/build/system/mcp-servers/admin/scan-codes.js +17 -1
  96. package/build/system/mcp-servers/admin/schemas.d.ts +643 -25
  97. package/build/system/mcp-servers/admin/schemas.js +127 -19
  98. package/build/system/mcp-servers/admin/users.js +3 -1
  99. package/build/system/mcp-servers/human-queue-schemas.d.ts +2 -2
  100. package/build/system/seed/tool-manifests-admin.d.ts +2283 -0
  101. package/build/system/seed/tool-manifests-admin.js +8 -5
  102. package/build/tsconfig.tsbuildinfo +1 -1
  103. package/build/types/analytics.d.ts +154 -0
  104. package/build/types/analytics.js +14 -0
  105. package/build/types/facets.d.ts +13 -0
  106. package/build/types/index.d.ts +5 -2
  107. package/build/types/index.js +5 -1
  108. package/build/types/scan-choice.d.ts +49 -0
  109. package/build/types/scan-choice.js +9 -0
  110. package/build/types/scan-code.d.ts +72 -1
  111. package/build/types/scan-code.js +30 -1
  112. package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js → AdminDashboard-DJ3LJQ09.js} +2 -2
  113. package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js.map → AdminDashboard-DJ3LJQ09.js.map} +1 -1
  114. package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js → AgentConfigPage-BMMvaD0z.js} +2 -2
  115. package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js.map → AgentConfigPage-BMMvaD0z.js.map} +1 -1
  116. package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js → AgentDetailPage-C6wfsnRe.js} +2 -2
  117. package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js.map → AgentDetailPage-C6wfsnRe.js.map} +1 -1
  118. package/dashboard/dist/assets/AgentsPage-Cwqka7nE.js +2 -0
  119. package/dashboard/dist/assets/{AgentsPage-CToVu1qj.js.map → AgentsPage-Cwqka7nE.js.map} +1 -1
  120. package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js +2 -0
  121. package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js.map +1 -0
  122. package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js → BotPicker-BBkJBXZB.js} +2 -2
  123. package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js.map → BotPicker-BBkJBXZB.js.map} +1 -1
  124. package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js → CapabilitiesPage-wxmE4917.js} +2 -2
  125. package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js.map → CapabilitiesPage-wxmE4917.js.map} +1 -1
  126. package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js → CollapsibleSection-B3FsrHwH.js} +2 -2
  127. package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js.map → CollapsibleSection-B3FsrHwH.js.map} +1 -1
  128. package/dashboard/dist/assets/CountdownTimer-B3nCqJdC.js +2 -0
  129. package/dashboard/dist/assets/CountdownTimer-B3nCqJdC.js.map +1 -0
  130. package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js → CredentialsPage-Bv875IHe.js} +2 -2
  131. package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js.map → CredentialsPage-Bv875IHe.js.map} +1 -1
  132. package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js → CronLabel-CSzjWuwj.js} +2 -2
  133. package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js.map → CronLabel-CSzjWuwj.js.map} +1 -1
  134. package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js → CustomDurationPicker-CCpqf3e4.js} +2 -2
  135. package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js.map → CustomDurationPicker-CCpqf3e4.js.map} +1 -1
  136. package/dashboard/dist/assets/{DropZone-CL9gA7pu.js → DropZone-CJkk-U3o.js} +2 -2
  137. package/dashboard/dist/assets/{DropZone-CL9gA7pu.js.map → DropZone-CJkk-U3o.js.map} +1 -1
  138. package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js → ElapsedCell-WV6pUaKo.js} +2 -2
  139. package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js.map → ElapsedCell-WV6pUaKo.js.map} +1 -1
  140. package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js +2 -0
  141. package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js.map +1 -0
  142. package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js → EscalationListSchemaPage-CTQCALw4.js} +3 -3
  143. package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js.map → EscalationListSchemaPage-CTQCALw4.js.map} +1 -1
  144. package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js → EscalationSchemaPage-D_UgP0pv.js} +3 -3
  145. package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js.map → EscalationSchemaPage-D_UgP0pv.js.map} +1 -1
  146. package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js → EscalationsOverview-DuIUyxr0.js} +2 -2
  147. package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js.map → EscalationsOverview-DuIUyxr0.js.map} +1 -1
  148. package/dashboard/dist/assets/EventTable-BV6unphX.js +2 -0
  149. package/dashboard/dist/assets/EventTable-BV6unphX.js.map +1 -0
  150. package/dashboard/dist/assets/FilterBar-DYFgzXNB.js +2 -0
  151. package/dashboard/dist/assets/FilterBar-DYFgzXNB.js.map +1 -0
  152. package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js → GraphInvokePage-BGHVUipJ.js} +2 -2
  153. package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js.map → GraphInvokePage-BGHVUipJ.js.map} +1 -1
  154. package/dashboard/dist/assets/HomePage-B-S2cK3E.js +2 -0
  155. package/dashboard/dist/assets/{HomePage-Bcq10Bxx.js.map → HomePage-B-S2cK3E.js.map} +1 -1
  156. package/dashboard/dist/assets/ListToolbar-Bl7F3A28.js +2 -0
  157. package/dashboard/dist/assets/{ListToolbar-IPXsTb3Q.js.map → ListToolbar-Bl7F3A28.js.map} +1 -1
  158. package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js → McpOverview-_T9IsCD_.js} +2 -2
  159. package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js.map → McpOverview-_T9IsCD_.js.map} +1 -1
  160. package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js → McpQueryDetailPage-DtsVqKPw.js} +2 -2
  161. package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js.map → McpQueryDetailPage-DtsVqKPw.js.map} +1 -1
  162. package/dashboard/dist/assets/McpQueryPage-DX5u-1bx.js +2 -0
  163. package/dashboard/dist/assets/{McpQueryPage-CNsuiw_q.js.map → McpQueryPage-DX5u-1bx.js.map} +1 -1
  164. package/dashboard/dist/assets/McpRunDetailPage-BhcqqtYS.js +2 -0
  165. package/dashboard/dist/assets/McpRunDetailPage-BhcqqtYS.js.map +1 -0
  166. package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js → McpRunsPage-L-1y8wnX.js} +2 -2
  167. package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js.map → McpRunsPage-L-1y8wnX.js.map} +1 -1
  168. package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js → NamespacePill-in1SLd0W.js} +2 -2
  169. package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js.map → NamespacePill-in1SLd0W.js.map} +1 -1
  170. package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js +3 -0
  171. package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js.map +1 -0
  172. package/dashboard/dist/assets/OperatorDashboard-CIbDzOlh.js +2 -0
  173. package/dashboard/dist/assets/{OperatorDashboard-C-jE0IRA.js.map → OperatorDashboard-CIbDzOlh.js.map} +1 -1
  174. package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js → PageHeader-BJgWMZtw.js} +2 -2
  175. package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js.map → PageHeader-BJgWMZtw.js.map} +1 -1
  176. package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js → PageHeaderWithStats-Ccio4vyG.js} +2 -2
  177. package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js.map → PageHeaderWithStats-Ccio4vyG.js.map} +1 -1
  178. package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js → PersonaDetailPage-BOaf0TW1.js} +2 -2
  179. package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js.map → PersonaDetailPage-BOaf0TW1.js.map} +1 -1
  180. package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js → PersonasPage-DSdRb90f.js} +2 -2
  181. package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js.map → PersonasPage-DSdRb90f.js.map} +1 -1
  182. package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js → ProcessDetailPage-DN9NqfeP.js} +2 -2
  183. package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js.map → ProcessDetailPage-DN9NqfeP.js.map} +1 -1
  184. package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js → ProcessesListPage-CfQEWaD4.js} +2 -2
  185. package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js.map → ProcessesListPage-CfQEWaD4.js.map} +1 -1
  186. package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js +8 -0
  187. package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js.map +1 -0
  188. package/dashboard/dist/assets/{RolePill-CnuBPhPw.js → RolePill-BNAP-uK6.js} +2 -2
  189. package/dashboard/dist/assets/{RolePill-CnuBPhPw.js.map → RolePill-BNAP-uK6.js.map} +1 -1
  190. package/dashboard/dist/assets/RolesPage-DCnW0VmD.js +2 -0
  191. package/dashboard/dist/assets/RolesPage-DCnW0VmD.js.map +1 -0
  192. package/dashboard/dist/assets/RunAsSelector-twbuX7fB.js +2 -0
  193. package/dashboard/dist/assets/{RunAsSelector-CS3KQ-BF.js.map → RunAsSelector-twbuX7fB.js.map} +1 -1
  194. package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js +2 -0
  195. package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js.map +1 -0
  196. package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js +2 -0
  197. package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js.map +1 -0
  198. package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js +2 -0
  199. package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js.map +1 -0
  200. package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js → ScopeBadge-BG7KkZ8Q.js} +2 -2
  201. package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js.map → ScopeBadge-BG7KkZ8Q.js.map} +1 -1
  202. package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js +2 -0
  203. package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js.map +1 -0
  204. package/dashboard/dist/assets/StickyPagination-DIeYMPPd.js +2 -0
  205. package/dashboard/dist/assets/StickyPagination-DIeYMPPd.js.map +1 -0
  206. package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js → StreamMessageDetail-gU4CUeQI.js} +2 -2
  207. package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js.map → StreamMessageDetail-gU4CUeQI.js.map} +1 -1
  208. package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js → SwimlaneTimeline-Br-nBA4l.js} +2 -2
  209. package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js.map → SwimlaneTimeline-Br-nBA4l.js.map} +1 -1
  210. package/dashboard/dist/assets/{TagInput-BbZ25nNe.js → TagInput-CvM5n6ww.js} +2 -2
  211. package/dashboard/dist/assets/{TagInput-BbZ25nNe.js.map → TagInput-CvM5n6ww.js.map} +1 -1
  212. package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js → TaskDetailPage-_9cr_R0u.js} +2 -2
  213. package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js.map → TaskDetailPage-_9cr_R0u.js.map} +1 -1
  214. package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js → TaskQueuePill-D4JPHXOq.js} +2 -2
  215. package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js.map → TaskQueuePill-D4JPHXOq.js.map} +1 -1
  216. package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js → TasksListPage-DVENC9Jp.js} +2 -2
  217. package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js.map → TasksListPage-DVENC9Jp.js.map} +1 -1
  218. package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js → TimeAgo-C9yYnOui.js} +2 -2
  219. package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js.map → TimeAgo-C9yYnOui.js.map} +1 -1
  220. package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js → TimestampCell-DoB8cYgw.js} +2 -2
  221. package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js.map → TimestampCell-DoB8cYgw.js.map} +1 -1
  222. package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js → ToolPill-BUjbC-Tj.js} +2 -2
  223. package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js.map → ToolPill-BUjbC-Tj.js.map} +1 -1
  224. package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js → ToolTestPanel-CBtsIP8K.js} +2 -2
  225. package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js.map → ToolTestPanel-CBtsIP8K.js.map} +1 -1
  226. package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js → TopicDetailPage-mR4Jaz83.js} +4 -4
  227. package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js.map → TopicDetailPage-mR4Jaz83.js.map} +1 -1
  228. package/dashboard/dist/assets/TopicsPage-CP7HFxIC.js +2 -0
  229. package/dashboard/dist/assets/{TopicsPage-1VAc29Qw.js.map → TopicsPage-CP7HFxIC.js.map} +1 -1
  230. package/dashboard/dist/assets/{UserName-DikzjQHJ.js → UserName-BnLF6yhz.js} +2 -2
  231. package/dashboard/dist/assets/{UserName-DikzjQHJ.js.map → UserName-BnLF6yhz.js.map} +1 -1
  232. package/dashboard/dist/assets/WorkflowExecutionPage-xL956RZi.js +2 -0
  233. package/dashboard/dist/assets/WorkflowExecutionPage-xL956RZi.js.map +1 -0
  234. package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js → WorkflowPill-tXU0-eXu.js} +2 -2
  235. package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js.map → WorkflowPill-tXU0-eXu.js.map} +1 -1
  236. package/dashboard/dist/assets/WorkflowsDashboard-B-u7zFKM.js +2 -0
  237. package/dashboard/dist/assets/{WorkflowsDashboard-BMQd_0tW.js.map → WorkflowsDashboard-B-u7zFKM.js.map} +1 -1
  238. package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js → WorkflowsOverview-CqZVarK-.js} +2 -2
  239. package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js.map → WorkflowsOverview-CqZVarK-.js.map} +1 -1
  240. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js → YamlWorkflowDetailPage-DiFLavW0.js} +10 -10
  241. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js.map → YamlWorkflowDetailPage-DiFLavW0.js.map} +1 -1
  242. package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js → YamlWorkflowsPage-BuQM6uZA.js} +2 -2
  243. package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js.map → YamlWorkflowsPage-BuQM6uZA.js.map} +1 -1
  244. package/dashboard/dist/assets/{agents-BZJLIJ4h.js → agents-DU9GPovp.js} +2 -2
  245. package/dashboard/dist/assets/{agents-BZJLIJ4h.js.map → agents-DU9GPovp.js.map} +1 -1
  246. package/dashboard/dist/assets/{bots-ClLcDGJb.js → bots-Cy-Hmg7w.js} +2 -2
  247. package/dashboard/dist/assets/{bots-ClLcDGJb.js.map → bots-Cy-Hmg7w.js.map} +1 -1
  248. package/dashboard/dist/assets/capabilities-sSJJqrp-.js +2 -0
  249. package/dashboard/dist/assets/{capabilities-IaCcS7ge.js.map → capabilities-sSJJqrp-.js.map} +1 -1
  250. package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js → controlplane-TVCjDHQ-.js} +2 -2
  251. package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js.map → controlplane-TVCjDHQ-.js.map} +1 -1
  252. package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js +2 -0
  253. package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js.map +1 -0
  254. package/dashboard/dist/assets/index-5TblaCXQ.css +1 -0
  255. package/dashboard/dist/assets/index-7BP6FaCZ.js +2 -0
  256. package/dashboard/dist/assets/{index-Dldi3Q3M.js.map → index-7BP6FaCZ.js.map} +1 -1
  257. package/dashboard/dist/assets/{index-BzkE48xJ.js → index-B7IaBPBg.js} +4 -4
  258. package/dashboard/dist/assets/{index-BzkE48xJ.js.map → index-B7IaBPBg.js.map} +1 -1
  259. package/dashboard/dist/assets/index-BE0phFw0.js +2 -0
  260. package/dashboard/dist/assets/{index-CLmZaNTK.js.map → index-BE0phFw0.js.map} +1 -1
  261. package/dashboard/dist/assets/{index-BqGnhkh0.js → index-BYNN9N1T.js} +2 -2
  262. package/dashboard/dist/assets/{index-BqGnhkh0.js.map → index-BYNN9N1T.js.map} +1 -1
  263. package/dashboard/dist/assets/{index-kiKZresb.js → index-CLPVqbVY.js} +2 -2
  264. package/dashboard/dist/assets/{index-kiKZresb.js.map → index-CLPVqbVY.js.map} +1 -1
  265. package/dashboard/dist/assets/{index-C3o4OisO.js → index-Cfv86_L9.js} +2 -2
  266. package/dashboard/dist/assets/{index-C3o4OisO.js.map → index-Cfv86_L9.js.map} +1 -1
  267. package/dashboard/dist/assets/{index-yGNt29V9.js → index-CtwbQ_-m.js} +2 -2
  268. package/dashboard/dist/assets/{index-yGNt29V9.js.map → index-CtwbQ_-m.js.map} +1 -1
  269. package/dashboard/dist/assets/index-DOai950R.js +3 -0
  270. package/dashboard/dist/assets/index-DOai950R.js.map +1 -0
  271. package/dashboard/dist/assets/index-DTtHNC-D.js +5 -0
  272. package/dashboard/dist/assets/{index-CvNBdkB1.js.map → index-DTtHNC-D.js.map} +1 -1
  273. package/dashboard/dist/assets/{index-CJu2PBNx.js → index-DsWnVyVN.js} +2 -2
  274. package/dashboard/dist/assets/{index-CJu2PBNx.js.map → index-DsWnVyVN.js.map} +1 -1
  275. package/dashboard/dist/assets/{index-D0zFReGL.js → index-Dy-MMYti.js} +2 -2
  276. package/dashboard/dist/assets/{index-D0zFReGL.js.map → index-Dy-MMYti.js.map} +1 -1
  277. package/dashboard/dist/assets/index-errgQT5x.js +65 -0
  278. package/dashboard/dist/assets/index-errgQT5x.js.map +1 -0
  279. package/dashboard/dist/assets/{index-CmnNqpWg.js → index-fgBDhnI6.js} +2 -2
  280. package/dashboard/dist/assets/{index-CmnNqpWg.js.map → index-fgBDhnI6.js.map} +1 -1
  281. package/dashboard/dist/assets/{knowledge-DWLxGTib.js → knowledge-arh4NfmL.js} +2 -2
  282. package/dashboard/dist/assets/{knowledge-DWLxGTib.js.map → knowledge-arh4NfmL.js.map} +1 -1
  283. package/dashboard/dist/assets/{mcp-B6AARZ2I.js → mcp-QGf5jHCo.js} +2 -2
  284. package/dashboard/dist/assets/{mcp-B6AARZ2I.js.map → mcp-QGf5jHCo.js.map} +1 -1
  285. package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js → mcp-query-BEJN1nMZ.js} +2 -2
  286. package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js.map → mcp-query-BEJN1nMZ.js.map} +1 -1
  287. package/dashboard/dist/assets/{personas-Cmz2SAEU.js → personas-DYtw1COf.js} +2 -2
  288. package/dashboard/dist/assets/{personas-Cmz2SAEU.js.map → personas-DYtw1COf.js.map} +1 -1
  289. package/dashboard/dist/assets/{pipelines-CSgfVCMy.js → pipelines-Byi6PnbE.js} +2 -2
  290. package/dashboard/dist/assets/{pipelines-CSgfVCMy.js.map → pipelines-Byi6PnbE.js.map} +1 -1
  291. package/dashboard/dist/assets/{tasks-UOtUkDk-.js → tasks-D0SQdENz.js} +2 -2
  292. package/dashboard/dist/assets/{tasks-UOtUkDk-.js.map → tasks-D0SQdENz.js.map} +1 -1
  293. package/dashboard/dist/assets/{topics-Df5hGh6o.js → topics-DgDv5ZXP.js} +2 -2
  294. package/dashboard/dist/assets/{topics-Df5hGh6o.js.map → topics-DgDv5ZXP.js.map} +1 -1
  295. package/dashboard/dist/assets/useEventHooks-DZaYzE7s.js +2 -0
  296. package/dashboard/dist/assets/{useEventHooks-PDbuSJ12.js.map → useEventHooks-DZaYzE7s.js.map} +1 -1
  297. package/dashboard/dist/assets/{useNamespace-tZSOlge3.js → useNamespace-C1OqiNXN.js} +2 -2
  298. package/dashboard/dist/assets/{useNamespace-tZSOlge3.js.map → useNamespace-C1OqiNXN.js.map} +1 -1
  299. package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js → useYamlActivityEvents-CkmXDm-Z.js} +2 -2
  300. package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js.map → useYamlActivityEvents-CkmXDm-Z.js.map} +1 -1
  301. package/dashboard/dist/assets/{users-G8qwyZKS.js → users-D4DCFPH1.js} +2 -2
  302. package/dashboard/dist/assets/{users-G8qwyZKS.js.map → users-D4DCFPH1.js.map} +1 -1
  303. package/dashboard/dist/assets/{vendor-icons-BpZiWH2f.js → vendor-icons-BxuyFxH2.js} +156 -136
  304. package/dashboard/dist/assets/vendor-icons-BxuyFxH2.js.map +1 -0
  305. package/dashboard/dist/assets/{workflows-DbPqi1TW.js → workflows-qyc0ku_5.js} +2 -2
  306. package/dashboard/dist/assets/{workflows-DbPqi1TW.js.map → workflows-qyc0ku_5.js.map} +1 -1
  307. package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js → yaml-workflows-DWFww9Xn.js} +2 -2
  308. package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js.map → yaml-workflows-DWFww9Xn.js.map} +1 -1
  309. package/dashboard/dist/index.html +3 -3
  310. package/docs/api/http/escalations.md +133 -0
  311. package/docs/api/http/roles.md +6 -0
  312. package/docs/api/mcp/admin.md +53 -0
  313. package/docs/api/sdk/escalations.md +58 -0
  314. package/docs/cli.md +11 -0
  315. package/docs/dashboard.md +22 -20
  316. package/docs/data.md +12 -4
  317. package/docs/design-principles.md +9 -7
  318. package/docs/escalation-analytics.md +251 -0
  319. package/docs/hitl/roles.md +1 -1
  320. package/docs/hitl/x-lt-embed.md +8 -4
  321. package/docs/hitl/x-lt-footer.md +67 -0
  322. package/docs/hitl/x-lt-list-schema.md +10 -3
  323. package/docs/hitl-guide.md +11 -2
  324. package/docs/iam.md +12 -0
  325. package/docs/operations.md +17 -0
  326. package/docs/scan-codes.md +112 -0
  327. package/docs/sdk.md +1 -1
  328. package/package.json +2 -1
  329. package/dashboard/dist/assets/AgentsPage-CToVu1qj.js +0 -2
  330. package/dashboard/dist/assets/AvailableEscalationsPage-DldboL4W.js +0 -2
  331. package/dashboard/dist/assets/AvailableEscalationsPage-DldboL4W.js.map +0 -1
  332. package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js +0 -2
  333. package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js.map +0 -1
  334. package/dashboard/dist/assets/EventTable-CwPWl163.js +0 -2
  335. package/dashboard/dist/assets/EventTable-CwPWl163.js.map +0 -1
  336. package/dashboard/dist/assets/FilterBar-D7GghUsU.js +0 -2
  337. package/dashboard/dist/assets/FilterBar-D7GghUsU.js.map +0 -1
  338. package/dashboard/dist/assets/HomePage-Bcq10Bxx.js +0 -2
  339. package/dashboard/dist/assets/ListToolbar-IPXsTb3Q.js +0 -2
  340. package/dashboard/dist/assets/McpQueryPage-CNsuiw_q.js +0 -2
  341. package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js +0 -2
  342. package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js.map +0 -1
  343. package/dashboard/dist/assets/OperationsPage-DvWrLuH6.js +0 -2
  344. package/dashboard/dist/assets/OperationsPage-DvWrLuH6.js.map +0 -1
  345. package/dashboard/dist/assets/OperatorDashboard-C-jE0IRA.js +0 -2
  346. package/dashboard/dist/assets/RoleDetailPage-BKkUvTO-.js +0 -8
  347. package/dashboard/dist/assets/RoleDetailPage-BKkUvTO-.js.map +0 -1
  348. package/dashboard/dist/assets/RolesPage-BHzWK9n6.js +0 -2
  349. package/dashboard/dist/assets/RolesPage-BHzWK9n6.js.map +0 -1
  350. package/dashboard/dist/assets/RunAsSelector-CS3KQ-BF.js +0 -2
  351. package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js +0 -2
  352. package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js.map +0 -1
  353. package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js +0 -2
  354. package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js.map +0 -1
  355. package/dashboard/dist/assets/StickyPagination-hMrnLXde.js +0 -2
  356. package/dashboard/dist/assets/StickyPagination-hMrnLXde.js.map +0 -1
  357. package/dashboard/dist/assets/TopicsPage-1VAc29Qw.js +0 -2
  358. package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js +0 -2
  359. package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js.map +0 -1
  360. package/dashboard/dist/assets/WorkflowsDashboard-BMQd_0tW.js +0 -2
  361. package/dashboard/dist/assets/capabilities-IaCcS7ge.js +0 -2
  362. package/dashboard/dist/assets/escalation-columns-BY2mg9DY.js +0 -2
  363. package/dashboard/dist/assets/escalation-columns-BY2mg9DY.js.map +0 -1
  364. package/dashboard/dist/assets/index-CLmZaNTK.js +0 -2
  365. package/dashboard/dist/assets/index-CfAi1OsI.js +0 -65
  366. package/dashboard/dist/assets/index-CfAi1OsI.js.map +0 -1
  367. package/dashboard/dist/assets/index-CvNBdkB1.js +0 -5
  368. package/dashboard/dist/assets/index-Dldi3Q3M.js +0 -2
  369. package/dashboard/dist/assets/index-mKcQGi2B.js +0 -3
  370. package/dashboard/dist/assets/index-mKcQGi2B.js.map +0 -1
  371. package/dashboard/dist/assets/index-zQiUPfxA.css +0 -1
  372. package/dashboard/dist/assets/useEventHooks-PDbuSJ12.js +0 -2
  373. package/dashboard/dist/assets/vendor-icons-BpZiWH2f.js.map +0 -1
package/README.md CHANGED
@@ -4,9 +4,7 @@
4
4
 
5
5
  Durable platforms are built around determinism — that is their strength and their blind spot. They give you rich, first-class queues for deterministic work (retry, timeout, `backoffCoefficient`, exactly-once) and an `await condition()` to park a workflow until a signal arrives. All of it assumes the thing you are waiting on will, eventually, behave.
6
6
 
7
- Most of the work that decides an outcome behaves on its own schedule: an approval, a person, a shipment, a machine that needs service. You cannot set a `backoffCoefficient` on a person retrying someone who has not answered just asks twice. This is why "human-in-the-loop" keeps getting bolted on as a feature: the platform perfected the deterministic queue and left the non-deterministic one for you to improvise.
8
-
9
- Long Tail makes it a primitive. The same `condition()` wait — except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
7
+ Long Tail makes non-determinism a primitive. The same `condition()` wait except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
10
8
 
11
9
  ```bash
12
10
  npm install @hotmeshio/long-tail
@@ -14,7 +12,7 @@ npm install @hotmeshio/long-tail
14
12
 
15
13
  ## How it works
16
14
 
17
- One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for the one reality answers.
15
+ One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for non-determinism.
18
16
 
19
17
  ```typescript
20
18
  import { Durable } from '@hotmeshio/hotmesh';
@@ -0,0 +1,6 @@
1
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
2
+ import type { AggregateByFacetsInput, TimelineByFacetInput } from '../../types';
3
+ /** Grouped membership/dwell aggregate over the escalation intervals. */
4
+ export declare function aggregateByFacets(input: AggregateByFacetsInput, auth: LTApiAuth): Promise<LTApiResult>;
5
+ /** One entity's ordered interval sequence (gap-preserving). */
6
+ export declare function timelineByFacet(input: TimelineByFacetInput, auth: LTApiAuth): Promise<LTApiResult>;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.aggregateByFacets = aggregateByFacets;
37
+ exports.timelineByFacet = timelineByFacet;
38
+ const escalationService = __importStar(require("../../services/escalation"));
39
+ const escalation_1 = require("../../services/escalation");
40
+ const userService = __importStar(require("../../services/user"));
41
+ const features_1 = require("../../modules/features");
42
+ // ── Escalation analytics surface (public) ────────────────────────────────────
43
+ //
44
+ // Grouped/temporal reads over the pond (membership, dwell, timeline). Reads
45
+ // only, but reads that AGGREGATE other operators' items — so the gate is the
46
+ // same broad scope the faceted search uses (read_all per requested role), with
47
+ // one extension: these queries may span roles. A caller must hold read_all on
48
+ // EVERY role in the filter; a filter with no role scope is inherently
49
+ // cross-role and requires a global principal (superadmin / admin). Results are
50
+ // principal-independent once the gate passes, which is what makes the
51
+ // service-layer cache shareable.
52
+ //
53
+ // publicPaceBoard carve-out (mirrors GET /station-metrics, list.ts): with the
54
+ // flag on, any authenticated caller may run aggregates whose group keys are
55
+ // COLUMNS only — those emit counts/seconds, the exact data class the Pace
56
+ // Board already exposes to every login. A groupBy.facets grouping emits facet
57
+ // VALUES (entity ids) as group keys and always takes the strict gate, as does
58
+ // timelineByFacet (an entity's movement history is item-level disclosure).
59
+ async function callerMayReadPonds(userId, roles) {
60
+ if (await userService.hasGlobalEscalationAccess(userId))
61
+ return true;
62
+ if (!roles.length)
63
+ return false; // whole-pond / cross-role ⇒ global only
64
+ for (const role of roles) {
65
+ const scope = await userService.getRoleScope(userId, role);
66
+ if (scope?.read !== 'all')
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ async function effectiveRoles(query) {
72
+ // `entity` scopes to its derived system — the gate covers the same roles the
73
+ // query will actually touch. Resolution throws AnalyticsInputError (→ 400)
74
+ // for unknown keys, before any scope decision.
75
+ if (query?.entity) {
76
+ return (await escalationService.resolveEntitySystem(query.entity)).map((s) => s.role);
77
+ }
78
+ if (query?.role)
79
+ return [query.role];
80
+ if (query?.roles?.length)
81
+ return query.roles;
82
+ return [];
83
+ }
84
+ function deniedMessage(roles) {
85
+ return roles.length
86
+ ? `You must hold ${roles.map((r) => `"${r}"`).join(', ')} with full (read_all) scope or be a superadmin`
87
+ : 'Analytics without a role filter spans every pond — a global (superadmin/admin) principal is required';
88
+ }
89
+ function failure(err) {
90
+ if (err instanceof escalation_1.AnalyticsInputError)
91
+ return { status: 400, error: err.message };
92
+ return { status: 500, error: err.message };
93
+ }
94
+ /** Grouped membership/dwell aggregate over the escalation intervals. */
95
+ async function aggregateByFacets(input, auth) {
96
+ try {
97
+ const roles = await effectiveRoles(input?.query);
98
+ const countsOnly = !input?.groupBy?.facets?.length;
99
+ const publiclyReadable = countsOnly && (0, features_1.getFeatureFlags)().publicPaceBoard;
100
+ if (!publiclyReadable && !(await callerMayReadPonds(auth.userId, roles))) {
101
+ return { status: 403, error: deniedMessage(roles) };
102
+ }
103
+ const data = await escalationService.aggregateByFacets(input);
104
+ return { status: 200, data };
105
+ }
106
+ catch (err) {
107
+ return failure(err);
108
+ }
109
+ }
110
+ /** One entity's ordered interval sequence (gap-preserving). */
111
+ async function timelineByFacet(input, auth) {
112
+ try {
113
+ const roles = await effectiveRoles(input?.query);
114
+ if (!(await callerMayReadPonds(auth.userId, roles))) {
115
+ return { status: 403, error: deniedMessage(roles) };
116
+ }
117
+ const data = await escalationService.timelineByFacet(input);
118
+ return { status: 200, data };
119
+ }
120
+ catch (err) {
121
+ return failure(err);
122
+ }
123
+ }
@@ -7,3 +7,4 @@ export { resolveEscalation, resolveBySignalKey, resolveByIds, resolveAllOrNone }
7
7
  export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
8
8
  export { cancelSingleEscalation, bulkCancel } from './cancel';
9
9
  export { searchByFacets, claimGroups, claimByFacets } from './facets';
10
+ export { aggregateByFacets, timelineByFacet } from './analytics';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
3
+ exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
4
4
  var create_1 = require("./create");
5
5
  Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
6
6
  var list_1 = require("./list");
@@ -40,3 +40,6 @@ var facets_1 = require("./facets");
40
40
  Object.defineProperty(exports, "searchByFacets", { enumerable: true, get: function () { return facets_1.searchByFacets; } });
41
41
  Object.defineProperty(exports, "claimGroups", { enumerable: true, get: function () { return facets_1.claimGroups; } });
42
42
  Object.defineProperty(exports, "claimByFacets", { enumerable: true, get: function () { return facets_1.claimByFacets; } });
43
+ var analytics_1 = require("./analytics");
44
+ Object.defineProperty(exports, "aggregateByFacets", { enumerable: true, get: function () { return analytics_1.aggregateByFacets; } });
45
+ Object.defineProperty(exports, "timelineByFacet", { enumerable: true, get: function () { return analytics_1.timelineByFacet; } });
@@ -161,7 +161,7 @@ async function resolveByMetadata(input, auth) {
161
161
  const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
162
162
  let result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, enforcing.size > 0 ? [...enforcing] : null, null, input.extraFacets);
163
163
  if (result.outcome === 'validation_required' && result.row) {
164
- const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload);
164
+ const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload, undefined, resolveUserId);
165
165
  if (report)
166
166
  return (0, resolve_1.validationFailure)(report);
167
167
  result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, null, result.row.id, input.extraFacets);
@@ -98,7 +98,7 @@ async function resolveEscalation(input, auth) {
98
98
  // the escalation's resolved form schema BEFORE any resolution path runs.
99
99
  // Costs nothing when the role does not enforce (cached role set); the
100
100
  // task-fallback envelope read only happens for enforcing roles.
101
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation));
101
+ const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation), auth.userId);
102
102
  if (violation)
103
103
  return validationFailure(violation);
104
104
  // The resolver payload is stored exactly as submitted — its shape is the
@@ -181,7 +181,7 @@ async function resolveBySignalKey(input, auth) {
181
181
  return { status: 404, error: 'Escalation not found' };
182
182
  // Schema enforcement — the row (envelope included) is already loaded, so
183
183
  // this costs zero extra reads beyond the cached schema.
184
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload);
184
+ const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, undefined, auth.userId);
185
185
  if (violation)
186
186
  return validationFailure(violation);
187
187
  // The payload is delivered as the signal the parked workflow's condition()
@@ -247,7 +247,7 @@ async function resolveByIds(input, auth) {
247
247
  const fullRows = await escalationService.getEscalationsByIds(involved);
248
248
  const failed = [];
249
249
  for (const row of fullRows) {
250
- const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload);
250
+ const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload, undefined, auth.userId);
251
251
  if (report)
252
252
  failed.push({ id: row.id, report });
253
253
  }
@@ -346,7 +346,7 @@ async function resolveAllOrNone(input, auth) {
346
346
  const row = rowById.get(item.id);
347
347
  if (!row || !row.role || !enforcing.has(row.role))
348
348
  continue;
349
- const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload);
349
+ const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload, undefined, auth.userId);
350
350
  if (report)
351
351
  failed.push({ id: item.id, report });
352
352
  }
@@ -106,6 +106,10 @@ export declare function updateRole(input: {
106
106
  priority_threshold_minutes?: number | null;
107
107
  /** Escalation metadata key holding the age origin (ISO 8601 UTC timestamp). Falls back to created_at. */
108
108
  priority_facet?: string | null;
109
+ /** Escalation metadata key identifying the entity that moves through this role (e.g. serialNumber). */
110
+ entity_facet?: string | null;
111
+ /** How this role names the entity's states: 'role' (the station is the state) or 'subtype'. Null resets to 'role'. */
112
+ entity_state_source?: 'role' | 'subtype' | null;
109
113
  /** Turn server-side resolver schema validation on/off for this role. */
110
114
  enforce_schema?: boolean;
111
115
  /** Replace the upstream-input set (omitted = preserve; null or [] = clear). */
@@ -222,6 +222,12 @@ async function updateRole(input) {
222
222
  if (input.priority_facet != null && (typeof input.priority_facet !== 'string' || !facet_sql_1.FACET_KEY.test(input.priority_facet))) {
223
223
  return { status: 400, error: 'priority_facet must be a metadata key (letters, numbers, underscores) or null' };
224
224
  }
225
+ if (input.entity_facet != null && (typeof input.entity_facet !== 'string' || !facet_sql_1.FACET_KEY.test(input.entity_facet))) {
226
+ return { status: 400, error: 'entity_facet must be a metadata key (letters, numbers, underscores) or null' };
227
+ }
228
+ if (input.entity_state_source != null && input.entity_state_source !== 'role' && input.entity_state_source !== 'subtype') {
229
+ return { status: 400, error: "entity_state_source must be 'role', 'subtype', or null" };
230
+ }
225
231
  if (input.ops_visible !== undefined && typeof input.ops_visible !== 'boolean') {
226
232
  return { status: 400, error: 'ops_visible must be a boolean' };
227
233
  }
@@ -272,6 +278,8 @@ async function updateRole(input) {
272
278
  worker_count: input.worker_count,
273
279
  priority_threshold_minutes: input.priority_threshold_minutes,
274
280
  priority_facet: input.priority_facet,
281
+ entity_facet: input.entity_facet,
282
+ entity_state_source: input.entity_state_source,
275
283
  enforce_schema: input.enforce_schema,
276
284
  upstream_roles: input.upstream_roles,
277
285
  change_summary: input.change_summary,
@@ -0,0 +1,11 @@
1
+ import { type ScanChoiceExecuteRequest, type ScanExecuteResponse } from '../../types';
2
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
3
+ /**
4
+ * Execute one presented choice. The request is a POINTER — scheme/category/
5
+ * step/choice indices plus the escalation id the screen showed — and a
6
+ * pointer is never authority: the choice is re-read from live config, the
7
+ * row is re-located under the step's query, the identity gate re-applies,
8
+ * and the verb runs through the same atomic executors a direct scan uses
9
+ * (so a lost race is a structured CONFLICT, exactly as on double-scan).
10
+ */
11
+ export declare function executeScanChoice(input: ScanChoiceExecuteRequest, auth: LTApiAuth): Promise<LTApiResult<ScanExecuteResponse>>;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.executeScanChoice = executeScanChoice;
37
+ const scanCodeService = __importStar(require("../../services/scan-code"));
38
+ const escalationService = __importStar(require("../../services/escalation"));
39
+ const types_1 = require("../../types");
40
+ const identity_1 = require("./identity");
41
+ const context_1 = require("./context");
42
+ const locate_1 = require("./locate");
43
+ const verbs_1 = require("./verbs");
44
+ /**
45
+ * Execute one presented choice. The request is a POINTER — scheme/category/
46
+ * step/choice indices plus the escalation id the screen showed — and a
47
+ * pointer is never authority: the choice is re-read from live config, the
48
+ * row is re-located under the step's query, the identity gate re-applies,
49
+ * and the verb runs through the same atomic executors a direct scan uses
50
+ * (so a lost race is a structured CONFLICT, exactly as on double-scan).
51
+ */
52
+ async function executeScanChoice(input, auth) {
53
+ try {
54
+ if (!Number.isInteger(input?.schemeVersion) || typeof input?.category !== 'string'
55
+ || !Number.isInteger(input?.stepIndex) || !Number.isInteger(input?.choiceIndex)
56
+ || !input?.escalationId) {
57
+ return { status: 400, error: 'schemeVersion, category, stepIndex, choiceIndex, and escalationId are required' };
58
+ }
59
+ // 1. The pointer resolves against LIVE config — an edit between render
60
+ // and tap is a structured miss, never a stale execution.
61
+ const scheme = await scanCodeService.getScanScheme(input.schemeVersion);
62
+ const rule = await scanCodeService.getScanRule(input.schemeVersion, input.category);
63
+ const step = rule?.steps?.[input.stepIndex];
64
+ const choice = step?.choices?.[input.choiceIndex];
65
+ if (!scheme || !scheme.enabled || scheme.kind !== types_1.SCAN_SCHEME_KINDS.ACTION
66
+ || !rule || !rule.enabled || step?.verb !== types_1.SCAN_VERBS.PRESENT || !choice) {
67
+ return {
68
+ status: 200,
69
+ data: { outcome: types_1.SCAN_OUTCOMES.UNCONFIGURED, error: 'the presented choice is no longer configured' },
70
+ };
71
+ }
72
+ // 2. The acting grant, exchanged before anything reads or writes.
73
+ let effectiveAuth = auth;
74
+ let acting = false;
75
+ if (input.actingToken) {
76
+ const resolved = await (0, identity_1.resolveActingAuth)(input.actingToken);
77
+ if (!resolved.ok) {
78
+ return {
79
+ status: 200,
80
+ data: { outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED, notPrimed: rule.notPrimed, error: resolved.error },
81
+ };
82
+ }
83
+ effectiveAuth = resolved.auth;
84
+ acting = true;
85
+ }
86
+ // 3. The row anchors the target: the scheme's facet on the escalation the
87
+ // screen presented. A missing binding is loud misconfiguration.
88
+ const row = await escalationService.getEscalation(input.escalationId);
89
+ const target = row?.metadata?.[scheme.target_facet];
90
+ if (!row || typeof target !== 'string' || !target) {
91
+ return {
92
+ status: 200,
93
+ data: { outcome: types_1.SCAN_OUTCOMES.UNCONFIGURED, error: `escalation does not carry the scheme facet "${scheme.target_facet}"` },
94
+ };
95
+ }
96
+ const ctx = {
97
+ scheme,
98
+ rule,
99
+ parsed: { version: scheme.version, category: rule.category, target },
100
+ scannedAt: new Date().toISOString(),
101
+ auth: effectiveAuth,
102
+ stationAuth: auth,
103
+ acting,
104
+ };
105
+ // 4. The identity gate, per the choice.
106
+ if (choice.requireActingIdentity && !(await (0, identity_1.actingIdentitySatisfied)(step, ctx))) {
107
+ return decorate((0, context_1.notPrimed)(ctx), ctx, input);
108
+ }
109
+ // 5. The row must still match the step's query — the reality the screen
110
+ // showed. A row that moved on (resolved, claimed away, re-routed) is the
111
+ // same double-actor race a second scan loses.
112
+ const located = await (0, locate_1.locateForStep)(step, ctx, 2);
113
+ if (!located || !located.escalations.some((e) => e.id === input.escalationId)) {
114
+ return decorate((0, context_1.conflict)('the item is no longer in the presented state'), ctx, input);
115
+ }
116
+ // 6. Dispatch through the same atomic executors a direct scan uses.
117
+ const synthesized = { query: step.query, verb: choice.verb, params: choice.params };
118
+ const result = await (0, verbs_1.dispatchChoiceVerb)(synthesized, ctx, located.escalations[0]);
119
+ return decorate(result, ctx, input);
120
+ }
121
+ catch (err) {
122
+ return { status: 500, error: err.message };
123
+ }
124
+ }
125
+ /** Stamp the rule + pointer identity onto the outcome, mirroring execute. */
126
+ function decorate(result, ctx, input) {
127
+ if (result.data && typeof result.data === 'object' && 'outcome' in result.data) {
128
+ result.data = {
129
+ ...result.data,
130
+ parsed: ctx.parsed,
131
+ rule: { schemeVersion: ctx.rule.scheme_version, category: ctx.rule.category, name: ctx.rule.name },
132
+ stepIndex: input.stepIndex,
133
+ };
134
+ }
135
+ return result;
136
+ }
@@ -0,0 +1,24 @@
1
+ import * as scanCodeService from '../../services/scan-code';
2
+ import { type LTEscalationRecord, type ParsedScanCode, type ScanExecuteResponse, type ScanRule, type ScanScheme, type ScanStep } from '../../types';
3
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
4
+ /** Everything a step executor needs about the scan that reached it. */
5
+ export interface StepContext {
6
+ scheme: ScanScheme;
7
+ rule: ScanRule;
8
+ parsed: ParsedScanCode;
9
+ scannedAt: string;
10
+ /** The effective actor — the acting (badged) user when a grant rode the request. */
11
+ auth: LTApiAuth;
12
+ /** The authenticated principal (the device on a station deployment). */
13
+ stationAuth: LTApiAuth;
14
+ /** True when `auth` came from an acting-identity grant. */
15
+ acting: boolean;
16
+ }
17
+ export declare function targetFilter(step: ScanStep, ctx: StepContext): Record<string, any>;
18
+ export declare function templateContext(ctx: StepContext): scanCodeService.ScanTemplateContext;
19
+ export declare function provenance(ctx: StepContext): Record<string, any>;
20
+ export declare function interpolatedMetadata(step: ScanStep, ctx: StepContext): Record<string, any>;
21
+ export declare function executed(escalation: LTEscalationRecord | Record<string, any> | undefined, step: Pick<ScanStep, 'verb'>): LTApiResult<ScanExecuteResponse>;
22
+ export declare function forbidden(error?: string): LTApiResult<ScanExecuteResponse>;
23
+ export declare function conflict(error?: string): LTApiResult<ScanExecuteResponse>;
24
+ export declare function notPrimed(ctx: StepContext): LTApiResult<ScanExecuteResponse>;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.targetFilter = targetFilter;
37
+ exports.templateContext = templateContext;
38
+ exports.provenance = provenance;
39
+ exports.interpolatedMetadata = interpolatedMetadata;
40
+ exports.executed = executed;
41
+ exports.forbidden = forbidden;
42
+ exports.conflict = conflict;
43
+ exports.notPrimed = notPrimed;
44
+ const scanCodeService = __importStar(require("../../services/scan-code"));
45
+ const types_1 = require("../../types");
46
+ function targetFilter(step, ctx) {
47
+ return { [ctx.scheme.target_facet]: ctx.parsed.target, ...(step.query?.facets ?? {}) };
48
+ }
49
+ function templateContext(ctx) {
50
+ return { target: ctx.parsed.target, category: ctx.parsed.category, scannedAt: ctx.scannedAt };
51
+ }
52
+ function provenance(ctx) {
53
+ return {
54
+ [types_1.SCAN_PROVENANCE_KEYS.SCHEME]: ctx.scheme.version,
55
+ [types_1.SCAN_PROVENANCE_KEYS.CATEGORY]: ctx.parsed.category,
56
+ [types_1.SCAN_PROVENANCE_KEYS.ACTION_NAME]: ctx.rule.name,
57
+ [types_1.SCAN_PROVENANCE_KEYS.SCANNED_AT]: ctx.scannedAt,
58
+ // Under an acting identity the mutation attributes to the person; the
59
+ // device where it happened is the other half of the audit pair.
60
+ ...(ctx.acting ? { [types_1.SCAN_PROVENANCE_KEYS.STATION]: ctx.stationAuth.userId } : {}),
61
+ };
62
+ }
63
+ function interpolatedMetadata(step, ctx) {
64
+ return step.params?.metadata
65
+ ? scanCodeService.interpolateScanTemplate(step.params.metadata, templateContext(ctx))
66
+ : {};
67
+ }
68
+ function executed(escalation, step) {
69
+ return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.EXECUTED, verb: step.verb, escalation } };
70
+ }
71
+ function forbidden(error) {
72
+ return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.FORBIDDEN, error } };
73
+ }
74
+ function conflict(error) {
75
+ return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.CONFLICT, error } };
76
+ }
77
+ function notPrimed(ctx) {
78
+ return {
79
+ status: 200,
80
+ data: {
81
+ outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED,
82
+ notPrimed: ctx.rule.notPrimed,
83
+ error: 'an acting identity is required — scan your badge',
84
+ },
85
+ };
86
+ }
@@ -1,5 +1,6 @@
1
1
  import { type ScanExecuteRequest, type ScanExecuteResponse } from '../../types';
2
2
  import type { LTApiAuth, LTApiResult } from '../../types/sdk';
3
+ export type { StepContext } from './context';
3
4
  /**
4
5
  * Execute a raw scan code: parse → load the rule → walk its steps in order.
5
6
  * The first step whose condition matches performs its verb and answers; a