@graphrefly/ts 0.0.0 → 0.0.2

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 (405) hide show
  1. package/README.md +135 -0
  2. package/dist/actions-types-CSC3NMDl.d.ts +657 -0
  3. package/dist/actions-types-wl9Mgkmr.d.cts +657 -0
  4. package/dist/adapters/index.cjs +5219 -2974
  5. package/dist/adapters/index.cjs.map +1 -1
  6. package/dist/adapters/index.d.cts +204 -192
  7. package/dist/adapters/index.d.ts +204 -192
  8. package/dist/adapters/index.js +3685 -1833
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/adapters/nestjs/microservices.cjs +841 -0
  11. package/dist/adapters/nestjs/microservices.cjs.map +1 -0
  12. package/dist/adapters/nestjs/microservices.d.cts +45 -0
  13. package/dist/adapters/nestjs/microservices.d.ts +45 -0
  14. package/dist/adapters/nestjs/microservices.js +206 -0
  15. package/dist/adapters/nestjs/microservices.js.map +1 -0
  16. package/dist/adapters/nestjs/native.cjs +1391 -0
  17. package/dist/adapters/nestjs/native.cjs.map +1 -0
  18. package/dist/adapters/nestjs/native.d.cts +111 -0
  19. package/dist/adapters/nestjs/native.d.ts +111 -0
  20. package/dist/adapters/nestjs/native.js +577 -0
  21. package/dist/adapters/nestjs/native.js.map +1 -0
  22. package/dist/adapters/nestjs/websockets.cjs +924 -0
  23. package/dist/adapters/nestjs/websockets.cjs.map +1 -0
  24. package/dist/adapters/nestjs/websockets.d.cts +47 -0
  25. package/dist/adapters/nestjs/websockets.d.ts +47 -0
  26. package/dist/adapters/nestjs/websockets.js +286 -0
  27. package/dist/adapters/nestjs/websockets.js.map +1 -0
  28. package/dist/adapters/nestjs.cjs +1085 -0
  29. package/dist/adapters/nestjs.cjs.map +1 -0
  30. package/dist/adapters/nestjs.d.cts +385 -0
  31. package/dist/adapters/nestjs.d.ts +385 -0
  32. package/dist/adapters/nestjs.js +112 -0
  33. package/dist/adapters/nestjs.js.map +1 -0
  34. package/dist/adapters/observe-storage.d.cts +4 -4
  35. package/dist/adapters/observe-storage.d.ts +4 -4
  36. package/dist/adapters/observe-storage.js +5 -4
  37. package/dist/adapters/observe-storage.js.map +1 -1
  38. package/dist/adapters/react.cjs +166 -0
  39. package/dist/adapters/react.cjs.map +1 -0
  40. package/dist/adapters/react.d.cts +31 -0
  41. package/dist/adapters/react.d.ts +31 -0
  42. package/dist/adapters/react.js +51 -0
  43. package/dist/adapters/react.js.map +1 -0
  44. package/dist/adapters/solid.cjs +157 -0
  45. package/dist/adapters/solid.cjs.map +1 -0
  46. package/dist/adapters/solid.d.cts +26 -0
  47. package/dist/adapters/solid.d.ts +26 -0
  48. package/dist/adapters/solid.js +48 -0
  49. package/dist/adapters/solid.js.map +1 -0
  50. package/dist/adapters/svelte.cjs +148 -0
  51. package/dist/adapters/svelte.cjs.map +1 -0
  52. package/dist/adapters/svelte.d.cts +31 -0
  53. package/dist/adapters/svelte.d.ts +31 -0
  54. package/dist/adapters/svelte.js +46 -0
  55. package/dist/adapters/svelte.js.map +1 -0
  56. package/dist/adapters/vue.cjs +155 -0
  57. package/dist/adapters/vue.cjs.map +1 -0
  58. package/dist/adapters/vue.d.cts +26 -0
  59. package/dist/adapters/vue.d.ts +26 -0
  60. package/dist/adapters/vue.js +46 -0
  61. package/dist/adapters/vue.js.map +1 -0
  62. package/dist/agent-runtime-types-core-CaXfKNtY.d.cts +406 -0
  63. package/dist/agent-runtime-types-core-hU299uIC.d.ts +406 -0
  64. package/dist/agent-runtime-types-tool-BEpSINol.d.ts +695 -0
  65. package/dist/agent-runtime-types-tool-DninPEzk.d.cts +695 -0
  66. package/dist/agentic-memory-retention-BmGX368S.d.ts +14 -0
  67. package/dist/agentic-memory-retention-Ih1qhX9Z.d.cts +14 -0
  68. package/dist/agentic-memory-types-CVSUS6XR.d.ts +473 -0
  69. package/dist/agentic-memory-types-FnnYlVUs.d.cts +473 -0
  70. package/dist/capability-admission-BW2CziT6.d.ts +102 -0
  71. package/dist/capability-admission-lwSecxXs.d.cts +102 -0
  72. package/dist/chunk-2KUAG2GZ.js +9693 -0
  73. package/dist/chunk-2KUAG2GZ.js.map +1 -0
  74. package/dist/chunk-2NJP6GO4.js +1320 -0
  75. package/dist/chunk-2NJP6GO4.js.map +1 -0
  76. package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
  77. package/dist/{chunk-COHO25CZ.js → chunk-4NWSNI4K.js} +2232 -1672
  78. package/dist/chunk-4NWSNI4K.js.map +1 -0
  79. package/dist/{chunk-Z2ANQ6JW.js → chunk-4Q77MMJY.js} +2 -2
  80. package/dist/chunk-6E76H4OU.js +132 -0
  81. package/dist/chunk-6E76H4OU.js.map +1 -0
  82. package/dist/chunk-7GOTIIQ7.js +819 -0
  83. package/dist/chunk-7GOTIIQ7.js.map +1 -0
  84. package/dist/{chunk-D6BG7U6A.js → chunk-7HZRJMN6.js} +3 -3
  85. package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
  86. package/dist/{chunk-PKVBHGBM.js → chunk-CJIFGJQG.js} +7 -7
  87. package/dist/{chunk-G4M3NHRJ.js → chunk-CX6B6PO2.js} +93 -10
  88. package/dist/chunk-CX6B6PO2.js.map +1 -0
  89. package/dist/chunk-DGUM43GV.js +11 -0
  90. package/dist/chunk-DGUM43GV.js.map +1 -0
  91. package/dist/{chunk-JIMUDQN3.js → chunk-E4QCH32M.js} +449 -447
  92. package/dist/chunk-E4QCH32M.js.map +1 -0
  93. package/dist/{chunk-RIIOUTGM.js → chunk-ECURQ3HD.js} +19 -129
  94. package/dist/chunk-ECURQ3HD.js.map +1 -0
  95. package/dist/{chunk-2ILL7HQI.js → chunk-EOKT4QFF.js} +134 -128
  96. package/dist/chunk-EOKT4QFF.js.map +1 -0
  97. package/dist/{chunk-K3FXTC3I.js → chunk-HJACH5PU.js} +3 -3
  98. package/dist/{chunk-GTPCOEOZ.js → chunk-IDMLXLLG.js} +3 -3
  99. package/dist/{chunk-DKP56CSW.js → chunk-JKAYLDQV.js} +2 -2
  100. package/dist/{chunk-4VLAQHZI.js → chunk-K7FB3JTD.js} +17 -1
  101. package/dist/chunk-K7FB3JTD.js.map +1 -0
  102. package/dist/chunk-L6LDXRWE.js +219 -0
  103. package/dist/chunk-L6LDXRWE.js.map +1 -0
  104. package/dist/chunk-M7J6Z4IJ.js +1930 -0
  105. package/dist/chunk-M7J6Z4IJ.js.map +1 -0
  106. package/dist/chunk-MQEQMS7B.js +1009 -0
  107. package/dist/chunk-MQEQMS7B.js.map +1 -0
  108. package/dist/chunk-MTELVIYR.js +1421 -0
  109. package/dist/chunk-MTELVIYR.js.map +1 -0
  110. package/dist/chunk-PVC7WDKI.js +885 -0
  111. package/dist/chunk-PVC7WDKI.js.map +1 -0
  112. package/dist/chunk-RAHNUYA5.js +368 -0
  113. package/dist/chunk-RAHNUYA5.js.map +1 -0
  114. package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
  115. package/dist/chunk-S6HXABGL.js.map +1 -0
  116. package/dist/{chunk-I3IHOHCJ.js → chunk-SHZDP2MQ.js} +1181 -1001
  117. package/dist/chunk-SHZDP2MQ.js.map +1 -0
  118. package/dist/{chunk-Y3ZLRGHC.js → chunk-SIDJO2T4.js} +16 -16
  119. package/dist/chunk-STXRMPW4.js +4131 -0
  120. package/dist/chunk-STXRMPW4.js.map +1 -0
  121. package/dist/{chunk-JR4IKCR2.js → chunk-TPND5MJS.js} +5 -5
  122. package/dist/chunk-TQPCAIQI.js +612 -0
  123. package/dist/chunk-TQPCAIQI.js.map +1 -0
  124. package/dist/chunk-UT3MHJCW.js +49 -0
  125. package/dist/chunk-UT3MHJCW.js.map +1 -0
  126. package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
  127. package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
  128. package/dist/chunk-WQIA3GFB.js.map +1 -0
  129. package/dist/{chunk-DJC4CHLQ.js → chunk-YDWBXXQZ.js} +5 -5
  130. package/dist/{chunk-6PHB5CJS.js → chunk-ZLFRB6FI.js} +2 -2
  131. package/dist/composition/index.cjs +1256 -1059
  132. package/dist/composition/index.cjs.map +1 -1
  133. package/dist/composition/index.d.cts +4 -4
  134. package/dist/composition/index.d.ts +4 -4
  135. package/dist/composition/index.js +7 -6
  136. package/dist/core/index.cjs +1218 -1021
  137. package/dist/core/index.cjs.map +1 -1
  138. package/dist/core/index.d.cts +2 -2
  139. package/dist/core/index.d.ts +2 -2
  140. package/dist/core/index.js +5 -4
  141. package/dist/cqrs/index.cjs.map +1 -1
  142. package/dist/cqrs/index.d.cts +4 -4
  143. package/dist/cqrs/index.d.ts +4 -4
  144. package/dist/cqrs/index.js +3 -2
  145. package/dist/cqrs/index.js.map +1 -1
  146. package/dist/cqrs/messaging.cjs +312 -0
  147. package/dist/cqrs/messaging.cjs.map +1 -0
  148. package/dist/cqrs/messaging.d.cts +57 -0
  149. package/dist/cqrs/messaging.d.ts +57 -0
  150. package/dist/cqrs/messaging.js +274 -0
  151. package/dist/cqrs/messaging.js.map +1 -0
  152. package/dist/cqrs/work-queue.cjs +329 -0
  153. package/dist/cqrs/work-queue.cjs.map +1 -0
  154. package/dist/cqrs/work-queue.d.cts +90 -0
  155. package/dist/cqrs/work-queue.d.ts +90 -0
  156. package/dist/cqrs/work-queue.js +292 -0
  157. package/dist/cqrs/work-queue.js.map +1 -0
  158. package/dist/data/index.cjs +19 -0
  159. package/dist/data/index.cjs.map +1 -0
  160. package/dist/data/index.d.cts +36 -0
  161. package/dist/data/index.d.ts +36 -0
  162. package/dist/data/index.js +1 -0
  163. package/dist/data/index.js.map +1 -0
  164. package/dist/data-structures/index.cjs +1252 -1052
  165. package/dist/data-structures/index.cjs.map +1 -1
  166. package/dist/data-structures/index.d.cts +9 -8
  167. package/dist/data-structures/index.d.ts +9 -8
  168. package/dist/data-structures/index.js +9 -7
  169. package/dist/{describe-BZb7AS2y.d.ts → describe-B_A5fbXH.d.ts} +1 -1
  170. package/dist/{describe-Ciu8SUnN.d.cts → describe-CQRrkv-Q.d.cts} +1 -1
  171. package/dist/executors/tool-provider-adapters.cjs +3091 -0
  172. package/dist/executors/tool-provider-adapters.cjs.map +1 -0
  173. package/dist/executors/tool-provider-adapters.d.cts +174 -0
  174. package/dist/executors/tool-provider-adapters.d.ts +174 -0
  175. package/dist/executors/tool-provider-adapters.js +1336 -0
  176. package/dist/executors/tool-provider-adapters.js.map +1 -0
  177. package/dist/executors/tool-provider-runtime.cjs +5178 -0
  178. package/dist/executors/tool-provider-runtime.cjs.map +1 -0
  179. package/dist/executors/tool-provider-runtime.d.cts +17 -0
  180. package/dist/executors/tool-provider-runtime.d.ts +17 -0
  181. package/dist/executors/tool-provider-runtime.js +15 -0
  182. package/dist/executors/tool-provider-runtime.js.map +1 -0
  183. package/dist/executors/tool-provider.cjs +6392 -0
  184. package/dist/executors/tool-provider.cjs.map +1 -0
  185. package/dist/executors/tool-provider.d.cts +60 -0
  186. package/dist/executors/tool-provider.d.ts +60 -0
  187. package/dist/executors/tool-provider.js +89 -0
  188. package/dist/executors/tool-provider.js.map +1 -0
  189. package/dist/executors/work-queue.cjs +342 -0
  190. package/dist/executors/work-queue.cjs.map +1 -0
  191. package/dist/executors/work-queue.d.cts +90 -0
  192. package/dist/executors/work-queue.d.ts +90 -0
  193. package/dist/executors/work-queue.js +306 -0
  194. package/dist/executors/work-queue.js.map +1 -0
  195. package/dist/graph/index.cjs +1536 -1324
  196. package/dist/graph/index.cjs.map +1 -1
  197. package/dist/graph/index.d.cts +10 -9
  198. package/dist/graph/index.d.ts +10 -9
  199. package/dist/graph/index.js +22 -20
  200. package/dist/{graph-s23RbbFO.d.cts → graph-CWK3HLPB.d.cts} +134 -132
  201. package/dist/{graph-DfdF9zy4.d.ts → graph-ho5sotHP.d.ts} +134 -132
  202. package/dist/{index-SnzZu3x7.d.ts → index-CQWcE0Dw.d.ts} +18 -4
  203. package/dist/{index-CAEmLCYF.d.cts → index-DHA1i67c.d.cts} +18 -4
  204. package/dist/index.cjs +3331 -3020
  205. package/dist/index.cjs.map +1 -1
  206. package/dist/index.d.cts +14 -10
  207. package/dist/index.d.ts +14 -10
  208. package/dist/index.js +114 -108
  209. package/dist/inspection/boundary.cjs +98 -0
  210. package/dist/inspection/boundary.cjs.map +1 -0
  211. package/dist/inspection/boundary.d.cts +61 -0
  212. package/dist/inspection/boundary.d.ts +61 -0
  213. package/dist/inspection/boundary.js +75 -0
  214. package/dist/inspection/boundary.js.map +1 -0
  215. package/dist/measurements-C0mAvWU1.d.cts +164 -0
  216. package/dist/measurements-OMpCeBwh.d.ts +164 -0
  217. package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
  218. package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
  219. package/dist/messaging/index.cjs +756 -619
  220. package/dist/messaging/index.cjs.map +1 -1
  221. package/dist/messaging/index.d.cts +17 -226
  222. package/dist/messaging/index.d.ts +17 -226
  223. package/dist/messaging/index.js +19 -749
  224. package/dist/messaging/index.js.map +1 -1
  225. package/dist/operators/index.cjs +1256 -1059
  226. package/dist/operators/index.cjs.map +1 -1
  227. package/dist/operators/index.d.cts +6 -6
  228. package/dist/operators/index.d.ts +6 -6
  229. package/dist/operators/index.js +9 -8
  230. package/dist/orchestration/index.cjs +8664 -2617
  231. package/dist/orchestration/index.cjs.map +1 -1
  232. package/dist/orchestration/index.d.cts +171 -221
  233. package/dist/orchestration/index.d.ts +171 -221
  234. package/dist/orchestration/index.js +74 -982
  235. package/dist/orchestration/index.js.map +1 -1
  236. package/dist/orchestration/messaging.cjs +314 -0
  237. package/dist/orchestration/messaging.cjs.map +1 -0
  238. package/dist/orchestration/messaging.d.cts +56 -0
  239. package/dist/orchestration/messaging.d.ts +56 -0
  240. package/dist/orchestration/messaging.js +276 -0
  241. package/dist/orchestration/messaging.js.map +1 -0
  242. package/dist/orchestration/work-queue.cjs +1500 -0
  243. package/dist/orchestration/work-queue.cjs.map +1 -0
  244. package/dist/orchestration/work-queue.d.cts +196 -0
  245. package/dist/orchestration/work-queue.d.ts +196 -0
  246. package/dist/orchestration/work-queue.js +1289 -0
  247. package/dist/orchestration/work-queue.js.map +1 -0
  248. package/dist/patterns/event-flow.cjs +433 -0
  249. package/dist/patterns/event-flow.cjs.map +1 -0
  250. package/dist/patterns/event-flow.d.cts +115 -0
  251. package/dist/patterns/event-flow.d.ts +115 -0
  252. package/dist/patterns/event-flow.js +14 -0
  253. package/dist/patterns/event-flow.js.map +1 -0
  254. package/dist/patterns/index.cjs +748 -355
  255. package/dist/patterns/index.cjs.map +1 -1
  256. package/dist/patterns/index.d.cts +9 -5
  257. package/dist/patterns/index.d.ts +9 -5
  258. package/dist/patterns/index.js +13 -4
  259. package/dist/process-types-C9uMYz3i.d.ts +200 -0
  260. package/dist/process-types-h3uRlzDc.d.cts +200 -0
  261. package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-B9R0Bl1P.d.cts} +11 -41
  262. package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BXFrH0U2.d.ts} +11 -41
  263. package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BLGv8Xp8.d.cts} +5 -5
  264. package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-a4zD3665.d.ts} +5 -5
  265. package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-C_8sOfdS.d.cts} +7 -6
  266. package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-jle5dnok.d.ts} +7 -6
  267. package/dist/render/index.d.cts +3 -3
  268. package/dist/render/index.d.ts +3 -3
  269. package/dist/render/index.js +1 -0
  270. package/dist/scheduled-readiness-5rwQlyjV.d.ts +91 -0
  271. package/dist/scheduled-readiness-DpRY8jI0.d.cts +91 -0
  272. package/dist/semantic-memory-graph-C2ZUwIlq.d.ts +30 -0
  273. package/dist/semantic-memory-graph-DlZBD_Eu.d.cts +30 -0
  274. package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-types-BvzdqmkY.d.cts} +2 -28
  275. package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-types-Ci-OtahO.d.ts} +2 -28
  276. package/dist/solutions/index.cjs +6788 -2128
  277. package/dist/solutions/index.cjs.map +1 -1
  278. package/dist/solutions/index.d.cts +15 -519
  279. package/dist/solutions/index.d.ts +15 -519
  280. package/dist/solutions/index.js +91 -7
  281. package/dist/solutions/reactive-layout/browser/index.cjs +457 -0
  282. package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
  283. package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
  284. package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
  285. package/dist/solutions/reactive-layout/browser/index.js +69 -0
  286. package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
  287. package/dist/solutions/reactive-layout/index.cjs +4494 -0
  288. package/dist/solutions/reactive-layout/index.cjs.map +1 -0
  289. package/dist/solutions/reactive-layout/index.d.cts +37 -0
  290. package/dist/solutions/reactive-layout/index.d.ts +37 -0
  291. package/dist/solutions/reactive-layout/index.js +146 -0
  292. package/dist/solutions/reactive-layout/index.js.map +1 -0
  293. package/dist/solutions/reactive-layout/node-canvas/index.cjs +555 -0
  294. package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
  295. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
  296. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
  297. package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
  298. package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
  299. package/dist/solutions/reactive-layout/react-native/index.cjs +504 -0
  300. package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
  301. package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
  302. package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
  303. package/dist/solutions/reactive-layout/react-native/index.js +77 -0
  304. package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
  305. package/dist/solutions/reactive-layout/skia/index.cjs +557 -0
  306. package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
  307. package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
  308. package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
  309. package/dist/solutions/reactive-layout/skia/index.js +70 -0
  310. package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
  311. package/dist/solutions/work-item/actions.cjs +2345 -0
  312. package/dist/solutions/work-item/actions.cjs.map +1 -0
  313. package/dist/solutions/work-item/actions.d.cts +40 -0
  314. package/dist/solutions/work-item/actions.d.ts +40 -0
  315. package/dist/solutions/work-item/actions.js +2078 -0
  316. package/dist/solutions/work-item/actions.js.map +1 -0
  317. package/dist/solutions/work-item/scheduling.cjs +9797 -0
  318. package/dist/solutions/work-item/scheduling.cjs.map +1 -0
  319. package/dist/solutions/work-item/scheduling.d.cts +1868 -0
  320. package/dist/solutions/work-item/scheduling.d.ts +1868 -0
  321. package/dist/solutions/work-item/scheduling.js +146 -0
  322. package/dist/solutions/work-item/scheduling.js.map +1 -0
  323. package/dist/solutions/work-item/work-queue.cjs +306 -0
  324. package/dist/solutions/work-item/work-queue.cjs.map +1 -0
  325. package/dist/solutions/work-item/work-queue.d.cts +71 -0
  326. package/dist/solutions/work-item/work-queue.d.ts +71 -0
  327. package/dist/solutions/work-item/work-queue.js +270 -0
  328. package/dist/solutions/work-item/work-queue.js.map +1 -0
  329. package/dist/sources/browser.cjs +1399 -1052
  330. package/dist/sources/browser.cjs.map +1 -1
  331. package/dist/sources/browser.d.cts +33 -6
  332. package/dist/sources/browser.d.ts +33 -6
  333. package/dist/sources/browser.js +73 -6
  334. package/dist/sources/browser.js.map +1 -1
  335. package/dist/sources/index.cjs +1345 -1065
  336. package/dist/sources/index.cjs.map +1 -1
  337. package/dist/sources/index.d.cts +5 -5
  338. package/dist/sources/index.d.ts +5 -5
  339. package/dist/sources/index.js +7 -6
  340. package/dist/sources/node.cjs.map +1 -1
  341. package/dist/sources/node.d.cts +4 -4
  342. package/dist/sources/node.d.ts +4 -4
  343. package/dist/sources/node.js +2 -1
  344. package/dist/sources/node.js.map +1 -1
  345. package/dist/storage/browser.cjs +16 -0
  346. package/dist/storage/browser.cjs.map +1 -1
  347. package/dist/storage/browser.js +4 -3
  348. package/dist/storage/browser.js.map +1 -1
  349. package/dist/storage/index.cjs +16 -0
  350. package/dist/storage/index.cjs.map +1 -1
  351. package/dist/storage/index.d.cts +6 -5
  352. package/dist/storage/index.d.ts +6 -5
  353. package/dist/storage/index.js +10 -9
  354. package/dist/storage/node.cjs +16 -0
  355. package/dist/storage/node.cjs.map +1 -1
  356. package/dist/storage/node.js +4 -3
  357. package/dist/storage/node.js.map +1 -1
  358. package/dist/store-BmtEs9mG.d.ts +123 -0
  359. package/dist/store-PAAsYvML.d.cts +123 -0
  360. package/dist/testing/index.cjs +1 -0
  361. package/dist/testing/index.cjs.map +1 -1
  362. package/dist/testing/index.d.cts +1 -1
  363. package/dist/testing/index.d.ts +1 -1
  364. package/dist/testing/index.js +3 -2
  365. package/dist/types-BRNKoFHj.d.ts +357 -0
  366. package/dist/{types-h12mNYbq.d.ts → types-BS6CyR-x.d.cts} +49 -130
  367. package/dist/types-BWK2ay3e.d.cts +457 -0
  368. package/dist/types-BXKSAoE1.d.cts +357 -0
  369. package/dist/types-BaPpZItj.d.ts +457 -0
  370. package/dist/types-BhveCMg5.d.cts +274 -0
  371. package/dist/{types-bNMSWKqF.d.cts → types-C9NOgNJw.d.ts} +49 -130
  372. package/dist/types-CTsQ8Ww4.d.ts +274 -0
  373. package/dist/types-DL_05n2M.d.ts +34 -0
  374. package/dist/types-XDoqxYO9.d.cts +34 -0
  375. package/dist/work-item-runtime-types-BqtWnSCS.d.ts +138 -0
  376. package/dist/work-item-runtime-types-CHO03AKh.d.cts +138 -0
  377. package/dist/work-queue/index.cjs +1136 -0
  378. package/dist/work-queue/index.cjs.map +1 -0
  379. package/dist/work-queue/index.d.cts +21 -0
  380. package/dist/work-queue/index.d.ts +21 -0
  381. package/dist/work-queue/index.js +1082 -0
  382. package/dist/work-queue/index.js.map +1 -0
  383. package/package.json +603 -249
  384. package/dist/chunk-2ILL7HQI.js.map +0 -1
  385. package/dist/chunk-4VLAQHZI.js.map +0 -1
  386. package/dist/chunk-COHO25CZ.js.map +0 -1
  387. package/dist/chunk-DK554R7P.js.map +0 -1
  388. package/dist/chunk-G4M3NHRJ.js.map +0 -1
  389. package/dist/chunk-I3IHOHCJ.js.map +0 -1
  390. package/dist/chunk-JIMUDQN3.js.map +0 -1
  391. package/dist/chunk-RIIOUTGM.js.map +0 -1
  392. package/dist/chunk-SWTLEQL6.js.map +0 -1
  393. /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
  394. /package/dist/{chunk-Z2ANQ6JW.js.map → chunk-4Q77MMJY.js.map} +0 -0
  395. /package/dist/{chunk-D6BG7U6A.js.map → chunk-7HZRJMN6.js.map} +0 -0
  396. /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
  397. /package/dist/{chunk-PKVBHGBM.js.map → chunk-CJIFGJQG.js.map} +0 -0
  398. /package/dist/{chunk-K3FXTC3I.js.map → chunk-HJACH5PU.js.map} +0 -0
  399. /package/dist/{chunk-GTPCOEOZ.js.map → chunk-IDMLXLLG.js.map} +0 -0
  400. /package/dist/{chunk-DKP56CSW.js.map → chunk-JKAYLDQV.js.map} +0 -0
  401. /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-SIDJO2T4.js.map} +0 -0
  402. /package/dist/{chunk-JR4IKCR2.js.map → chunk-TPND5MJS.js.map} +0 -0
  403. /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
  404. /package/dist/{chunk-DJC4CHLQ.js.map → chunk-YDWBXXQZ.js.map} +0 -0
  405. /package/dist/{chunk-6PHB5CJS.js.map → chunk-ZLFRB6FI.js.map} +0 -0
@@ -0,0 +1,2345 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/solutions/work-item/actions.ts
21
+ var actions_exports = {};
22
+ __export(actions_exports, {
23
+ workItemDomainActionAdmissionProjector: () => workItemDomainActionAdmissionProjector,
24
+ workItemDomainActionApplicationProjector: () => workItemDomainActionApplicationProjector,
25
+ workItemDomainActionApplyPolicy: () => workItemDomainActionApplyPolicy,
26
+ workItemDomainActionCapabilityGuardProjector: () => workItemDomainActionCapabilityGuardProjector,
27
+ workItemDomainActionProposal: () => workItemDomainActionProposal,
28
+ workItemDomainActionProposalIntake: () => workItemDomainActionProposalIntake,
29
+ workItemDomainActionProposalIntakeProjector: () => workItemDomainActionProposalIntakeProjector
30
+ });
31
+ module.exports = __toCommonJS(actions_exports);
32
+
33
+ // src/protocol/messages.ts
34
+ var SENTINEL = void 0;
35
+
36
+ // src/ctx/types.ts
37
+ function depWaves(ctx, depIndex) {
38
+ return ctx.waveData[depIndex] ?? [];
39
+ }
40
+ function depBatch(ctx, depIndex) {
41
+ const waves = depWaves(ctx, depIndex);
42
+ if (waves.length === 0) return null;
43
+ const flattened = waves.flat().filter((v) => v !== SENTINEL);
44
+ return flattened.length === 0 ? [] : flattened;
45
+ }
46
+
47
+ // src/orchestration/work-item-runtime-shared.ts
48
+ function emitWorkItemAdmissionIssue(ctx, state, key, code, message, subjectId, sourceRefs2) {
49
+ if (state.issueKeys.has(key)) return;
50
+ state.issueKeys.add(key);
51
+ state.issueSeq += 1;
52
+ state.statusSeq += 1;
53
+ state.auditSeq += 1;
54
+ const issue2 = dataIssue(code, message, { subjectId, refs: sourceRefs2 });
55
+ const status = {
56
+ kind: "work-item-status",
57
+ statusId: `${subjectId ?? "work-item"}:mapping-issue:${state.statusSeq}`,
58
+ workItemId: subjectId ?? "unknown",
59
+ state: "mapping-issue",
60
+ sourceRefs: sourceRefs2,
61
+ issues: [issue2]
62
+ };
63
+ const audit = {
64
+ id: `${subjectId ?? "work-item"}:${code}:${state.auditSeq}`,
65
+ kind: "work-item-domain-action-admission-issue",
66
+ subjectId,
67
+ issueCode: code,
68
+ message,
69
+ sourceRefs: sourceRefs2
70
+ };
71
+ ctx.down([
72
+ ["DATA", { kind: "issue", issue: issue2 }],
73
+ ["DATA", { kind: "status", status }],
74
+ ["DATA", { kind: "audit", audit }]
75
+ ]);
76
+ }
77
+ function emptyWorkItemDomainActionAdmissionState() {
78
+ return {
79
+ proposals: /* @__PURE__ */ new Map(),
80
+ policies: /* @__PURE__ */ new Map(),
81
+ decisions: /* @__PURE__ */ new Map(),
82
+ admissionsById: /* @__PURE__ */ new Map(),
83
+ admissionsByProposal: /* @__PURE__ */ new Map(),
84
+ terminalDecisionIds: /* @__PURE__ */ new Set(),
85
+ issueKeys: /* @__PURE__ */ new Set(),
86
+ statusSeq: 0,
87
+ issueSeq: 0,
88
+ auditSeq: 0
89
+ };
90
+ }
91
+ function freezeWorkItemDomainActionAdmissionViews(state) {
92
+ return {
93
+ admissionsByProposal: new Map(state.admissionsByProposal),
94
+ admissionsByWorkItem: new Map(
95
+ Array.from(state.admissionsByWorkItem, ([key, value]) => [key, Object.freeze([...value])])
96
+ ),
97
+ issues: Object.freeze([...state.issues]),
98
+ audit: Object.freeze([...state.audit])
99
+ };
100
+ }
101
+ function workItemAdmissionProposalRefs(proposal) {
102
+ return uniqueSourceRefs([
103
+ ref("work-item", proposal.workItemId),
104
+ ref("work-item-domain-action-proposal", proposal.proposalId),
105
+ ref("effect-run", proposal.effectRunId),
106
+ ref("effect-run-result", proposal.effectRunResultId),
107
+ ref("work-item-evidence", proposal.evidenceId),
108
+ ref("work-item-effect-mapping-policy", proposal.policyId),
109
+ ...proposal.sourceRefs ?? []
110
+ ]);
111
+ }
112
+ function workItemAdmissionDecisionRefs(decision, proposal, policy) {
113
+ return uniqueSourceRefs([
114
+ ...proposal === void 0 ? [] : workItemAdmissionProposalRefs(proposal),
115
+ ref("work-item-domain-action-admission-decision", decision.decisionId),
116
+ ref("work-item-domain-action-admission", decision.admissionId),
117
+ ref("work-item-domain-action-proposal", decision.proposalId),
118
+ ...decision.policyId === void 0 ? [] : [ref("work-item-domain-action-admission-policy", decision.policyId)],
119
+ ...policy === void 0 ? [] : [ref("work-item-domain-action-admission-policy", policy.policyId)],
120
+ ...decision.targetProposalId === void 0 ? [] : [ref("work-item-domain-action-proposal", decision.targetProposalId)],
121
+ ...decision.targetAdmissionId === void 0 ? [] : [ref("work-item-domain-action-admission", decision.targetAdmissionId)],
122
+ ...decision.sourceRefs ?? []
123
+ ]);
124
+ }
125
+ function uniqueSourceRefs(sourceRefs2) {
126
+ const seen = /* @__PURE__ */ new Set();
127
+ const unique = [];
128
+ for (const sourceRef of sourceRefs2) {
129
+ const key = sourceRefKey(sourceRef);
130
+ if (seen.has(key)) continue;
131
+ seen.add(key);
132
+ unique.push(sourceRef);
133
+ }
134
+ return unique;
135
+ }
136
+ function sourceRefKey(sourceRef) {
137
+ return `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
138
+ }
139
+ function projectRuntimeFact(graph, runtime, name, factory, pick) {
140
+ return graph.node(
141
+ [runtime],
142
+ (ctx) => {
143
+ for (const fact of depBatch(ctx, 0) ?? []) {
144
+ const typed = fact;
145
+ const value = pick(typed);
146
+ if (value !== void 0) ctx.down([["DATA", value]]);
147
+ }
148
+ },
149
+ { name, factory }
150
+ );
151
+ }
152
+ function forEachPolicyDepBatch(ctx, start, count, fn) {
153
+ for (let i = 0; i < count; i += 1) {
154
+ for (const value of depBatch(ctx, start + i) ?? []) fn(value);
155
+ }
156
+ }
157
+ function dataIssue(code, message, opts = {}) {
158
+ return {
159
+ kind: "issue",
160
+ code,
161
+ message,
162
+ severity: opts.severity ?? "error",
163
+ subjectId: opts.subjectId,
164
+ refs: opts.refs?.map((r) => `${r.kind}:${r.id}`),
165
+ details: opts.details
166
+ };
167
+ }
168
+ function ref(kind, id) {
169
+ return { kind, id };
170
+ }
171
+
172
+ // src/orchestration/work-item-runtime-admission.ts
173
+ function workItemDomainActionAdmissionProjector(graph, opts) {
174
+ const name = opts.name ?? "workItemDomainActionAdmissions";
175
+ const policyDeps = opts.admissionPolicies ?? [];
176
+ const policyStart = 2;
177
+ const now = opts.now ?? Date.now;
178
+ const runtime = graph.node(
179
+ [opts.proposals, opts.decisions, ...policyDeps],
180
+ (ctx) => {
181
+ const state = ctx.state.get() ?? emptyWorkItemDomainActionAdmissionState();
182
+ for (const raw of depBatch(ctx, 0) ?? []) {
183
+ const proposal = raw;
184
+ if (state.proposals.has(proposal.proposalId)) {
185
+ emitWorkItemAdmissionIssue(
186
+ ctx,
187
+ state,
188
+ `duplicate-admission-proposal:${proposal.proposalId}`,
189
+ "duplicate-work-item-domain-action-proposal",
190
+ `WorkItemDomainActionProposal '${proposal.proposalId}' was already seen by the admission projector`,
191
+ proposal.workItemId,
192
+ workItemAdmissionProposalRefs(proposal)
193
+ );
194
+ continue;
195
+ }
196
+ state.proposals.set(proposal.proposalId, proposal);
197
+ }
198
+ forEachPolicyDepBatch(ctx, policyStart, policyDeps.length, (raw) => {
199
+ const policy = raw;
200
+ state.policies.set(policy.policyId, policy);
201
+ });
202
+ for (const raw of depBatch(ctx, 1) ?? []) {
203
+ const decision = raw;
204
+ if (state.decisions.has(decision.decisionId)) {
205
+ emitWorkItemAdmissionIssue(
206
+ ctx,
207
+ state,
208
+ `duplicate-admission-decision:${decision.decisionId}`,
209
+ "duplicate-work-item-domain-action-admission-decision",
210
+ `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' was already seen by the admission projector`,
211
+ decision.proposalId,
212
+ workItemAdmissionDecisionRefs(decision)
213
+ );
214
+ continue;
215
+ }
216
+ state.decisions.set(decision.decisionId, decision);
217
+ }
218
+ evaluateWorkItemDomainActionAdmissions(ctx, state, now());
219
+ ctx.state.set(state);
220
+ },
221
+ { name: `${name}/runtime`, factory: "workItemDomainActionAdmissionProjector", partial: true }
222
+ );
223
+ return {
224
+ admissions: projectRuntimeFact(
225
+ graph,
226
+ runtime,
227
+ `${name}/admissions`,
228
+ "workItemDomainActionAdmissions",
229
+ (fact) => fact.kind === "admission" ? fact.admission : void 0
230
+ ),
231
+ status: projectRuntimeFact(
232
+ graph,
233
+ runtime,
234
+ `${name}/status`,
235
+ "workItemDomainActionAdmissionStatus",
236
+ (fact) => fact.kind === "status" ? fact.status : void 0
237
+ ),
238
+ issues: projectRuntimeFact(
239
+ graph,
240
+ runtime,
241
+ `${name}/issues`,
242
+ "workItemDomainActionAdmissionIssues",
243
+ (fact) => fact.kind === "issue" ? fact.issue : void 0
244
+ ),
245
+ audit: projectRuntimeFact(
246
+ graph,
247
+ runtime,
248
+ `${name}/audit`,
249
+ "workItemDomainActionAdmissionAudit",
250
+ (fact) => fact.kind === "audit" ? fact.audit : void 0
251
+ ),
252
+ views: graph.node(
253
+ [runtime],
254
+ (ctx) => {
255
+ const state = ctx.state.get() ?? {
256
+ admissionsByProposal: /* @__PURE__ */ new Map(),
257
+ admissionsByWorkItem: /* @__PURE__ */ new Map(),
258
+ issues: [],
259
+ audit: []
260
+ };
261
+ for (const raw of depBatch(ctx, 0) ?? []) {
262
+ const fact = raw;
263
+ if (fact.kind === "admission") {
264
+ const admission = fact.admission;
265
+ state.admissionsByProposal.set(admission.proposalId, admission);
266
+ const byWorkItem = state.admissionsByWorkItem.get(admission.workItemId) ?? [];
267
+ byWorkItem.push(admission);
268
+ state.admissionsByWorkItem.set(admission.workItemId, byWorkItem);
269
+ } else if (fact.kind === "issue") state.issues.push(fact.issue);
270
+ else if (fact.kind === "audit") state.audit.push(fact.audit);
271
+ }
272
+ ctx.state.set(state);
273
+ ctx.down([["DATA", freezeWorkItemDomainActionAdmissionViews(state)]]);
274
+ },
275
+ { name: `${name}/views`, factory: "workItemDomainActionAdmissionViews" }
276
+ )
277
+ };
278
+ }
279
+ function evaluateWorkItemDomainActionAdmissions(ctx, state, admittedAtMs) {
280
+ let emitted = true;
281
+ let passes = 0;
282
+ while (emitted && passes <= state.decisions.size) {
283
+ emitted = false;
284
+ passes += 1;
285
+ for (const decision of state.decisions.values()) {
286
+ if (state.terminalDecisionIds.has(decision.decisionId)) continue;
287
+ emitted = evaluateWorkItemDomainActionAdmission(ctx, state, decision, admittedAtMs) || emitted;
288
+ }
289
+ }
290
+ }
291
+ function evaluateWorkItemDomainActionAdmission(ctx, state, decision, admittedAtMs) {
292
+ const proposal = state.proposals.get(decision.proposalId);
293
+ const proposalRefs = workItemAdmissionDecisionRefs(decision, proposal);
294
+ const subjectId = proposal?.workItemId ?? decision.proposalId;
295
+ if (proposal === void 0) {
296
+ emitWorkItemAdmissionIssue(
297
+ ctx,
298
+ state,
299
+ `missing-admission-proposal:${decision.decisionId}:${decision.proposalId}`,
300
+ "missing-work-item-domain-action-admission-proposal",
301
+ `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references missing proposal '${decision.proposalId}'`,
302
+ subjectId,
303
+ proposalRefs
304
+ );
305
+ return false;
306
+ }
307
+ const staleProposalRef = (decision.sourceRefs ?? []).find(
308
+ (sourceRef) => sourceRef.kind === "work-item-domain-action-proposal" && sourceRef.id !== decision.proposalId && sourceRef.id !== decision.targetProposalId
309
+ );
310
+ if (staleProposalRef !== void 0) {
311
+ emitWorkItemAdmissionIssue(
312
+ ctx,
313
+ state,
314
+ `stale-admission-proposal-ref:${decision.decisionId}:${staleProposalRef.id}`,
315
+ "stale-work-item-domain-action-admission-proposal-ref",
316
+ `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries stale proposal ref '${staleProposalRef.id}'`,
317
+ proposal.workItemId,
318
+ proposalRefs
319
+ );
320
+ state.terminalDecisionIds.add(decision.decisionId);
321
+ return false;
322
+ }
323
+ const policy = admissionPolicyForDecision(state, decision);
324
+ if (typeof policy === "string") {
325
+ emitWorkItemAdmissionIssue(
326
+ ctx,
327
+ state,
328
+ `${policy}:${decision.decisionId}:${decision.policyId ?? "missing"}`,
329
+ policy,
330
+ admissionPolicyIssueMessage(policy, decision),
331
+ proposal.workItemId,
332
+ proposalRefs
333
+ );
334
+ if (policy === "stale-work-item-domain-action-admission-policy-ref")
335
+ state.terminalDecisionIds.add(decision.decisionId);
336
+ return false;
337
+ }
338
+ if (policy !== void 0) {
339
+ const policyIssue = validateWorkItemAdmissionPolicy(policy, decision, proposal);
340
+ if (policyIssue !== void 0) {
341
+ emitWorkItemAdmissionIssue(
342
+ ctx,
343
+ state,
344
+ `${policyIssue.code}:${decision.decisionId}:${policy.policyId}`,
345
+ policyIssue.code,
346
+ policyIssue.message,
347
+ proposal.workItemId,
348
+ workItemAdmissionDecisionRefs(decision, proposal, policy)
349
+ );
350
+ return false;
351
+ }
352
+ }
353
+ const mergeIssue = validateWorkItemAdmissionMergeTarget(state, decision);
354
+ if (mergeIssue !== void 0) {
355
+ emitWorkItemAdmissionIssue(
356
+ ctx,
357
+ state,
358
+ `${mergeIssue.code}:${decision.decisionId}:${decision.targetProposalId ?? ""}:${decision.targetAdmissionId ?? ""}`,
359
+ mergeIssue.code,
360
+ mergeIssue.message,
361
+ proposal.workItemId,
362
+ proposalRefs
363
+ );
364
+ if (mergeIssue.code !== "unknown-work-item-domain-action-admission-merge-target")
365
+ state.terminalDecisionIds.add(decision.decisionId);
366
+ return false;
367
+ }
368
+ if (state.admissionsById.has(decision.admissionId)) {
369
+ emitWorkItemAdmissionIssue(
370
+ ctx,
371
+ state,
372
+ `duplicate-admission-id:${decision.admissionId}`,
373
+ "duplicate-work-item-domain-action-admission",
374
+ `WorkItemDomainActionAdmission '${decision.admissionId}' was already emitted`,
375
+ proposal.workItemId,
376
+ proposalRefs
377
+ );
378
+ state.terminalDecisionIds.add(decision.decisionId);
379
+ return false;
380
+ }
381
+ if (state.admissionsByProposal.has(decision.proposalId)) {
382
+ emitWorkItemAdmissionIssue(
383
+ ctx,
384
+ state,
385
+ `duplicate-admission-proposal-decision:${decision.proposalId}:${decision.decisionId}`,
386
+ "duplicate-work-item-domain-action-admission-proposal",
387
+ `WorkItemDomainActionProposal '${decision.proposalId}' already has an admission decision`,
388
+ proposal.workItemId,
389
+ proposalRefs
390
+ );
391
+ state.terminalDecisionIds.add(decision.decisionId);
392
+ return false;
393
+ }
394
+ const admissionState = admissionStateForOutcome(decision.outcome);
395
+ if (admissionState === void 0) {
396
+ emitWorkItemAdmissionIssue(
397
+ ctx,
398
+ state,
399
+ `unsupported-admission-outcome:${decision.decisionId}:${String(decision.outcome)}`,
400
+ "unsupported-work-item-domain-action-admission-outcome",
401
+ `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' uses unsupported outcome '${String(decision.outcome)}'`,
402
+ proposal.workItemId,
403
+ proposalRefs
404
+ );
405
+ state.terminalDecisionIds.add(decision.decisionId);
406
+ return false;
407
+ }
408
+ const admission = {
409
+ kind: "work-item-domain-action-admission",
410
+ admissionId: decision.admissionId,
411
+ proposalId: proposal.proposalId,
412
+ workItemId: proposal.workItemId,
413
+ actionKind: proposal.actionKind,
414
+ state: admissionState,
415
+ decisionId: decision.decisionId,
416
+ policyId: decision.policyId,
417
+ reason: decision.reason,
418
+ targetProposalId: decision.targetProposalId,
419
+ targetAdmissionId: decision.targetAdmissionId,
420
+ sourceRefs: workItemAdmissionDecisionRefs(decision, proposal, policy),
421
+ admittedAtMs: decision.decidedAtMs ?? admittedAtMs,
422
+ metadata: {
423
+ ...proposal.metadata ?? {},
424
+ ...policy?.metadata ?? {},
425
+ ...decision.metadata ?? {}
426
+ }
427
+ };
428
+ state.admissionsById.set(admission.admissionId, admission);
429
+ state.admissionsByProposal.set(admission.proposalId, admission);
430
+ state.terminalDecisionIds.add(decision.decisionId);
431
+ state.statusSeq += 1;
432
+ state.auditSeq += 1;
433
+ const statusState = workItemAdmissionStatusState(admission.state);
434
+ const status = {
435
+ kind: "work-item-status",
436
+ statusId: `${proposal.workItemId}:${statusState}:${state.statusSeq}`,
437
+ workItemId: proposal.workItemId,
438
+ state: statusState,
439
+ sourceRefs: admission.sourceRefs,
440
+ effectRunId: proposal.effectRunId,
441
+ evidenceId: proposal.evidenceId,
442
+ proposalId: proposal.proposalId,
443
+ metadata: {
444
+ actionKind: proposal.actionKind,
445
+ admissionId: admission.admissionId,
446
+ decisionId: decision.decisionId,
447
+ policyId: decision.policyId
448
+ }
449
+ };
450
+ const audit = {
451
+ id: `${proposal.workItemId}:${statusState}:${state.auditSeq}`,
452
+ kind: `work-item-domain-action-${admission.state}`,
453
+ subjectId: proposal.workItemId,
454
+ sourceRefs: admission.sourceRefs,
455
+ metadata: {
456
+ actionKind: proposal.actionKind,
457
+ admissionId: admission.admissionId,
458
+ decisionId: decision.decisionId,
459
+ policyId: decision.policyId,
460
+ proposalId: proposal.proposalId
461
+ }
462
+ };
463
+ ctx.down([
464
+ ["DATA", { kind: "admission", admission }],
465
+ ["DATA", { kind: "status", status }],
466
+ ["DATA", { kind: "audit", audit }]
467
+ ]);
468
+ return true;
469
+ }
470
+ function admissionPolicyForDecision(state, decision) {
471
+ if (decision.policyId === void 0) return void 0;
472
+ const stalePolicyRef = (decision.sourceRefs ?? []).find(
473
+ (sourceRef) => sourceRef.kind === "work-item-domain-action-admission-policy" && sourceRef.id !== decision.policyId
474
+ );
475
+ if (stalePolicyRef !== void 0) return "stale-work-item-domain-action-admission-policy-ref";
476
+ return state.policies.get(decision.policyId) ?? "missing-work-item-domain-action-admission-policy";
477
+ }
478
+ function admissionPolicyIssueMessage(code, decision) {
479
+ if (code === "missing-work-item-domain-action-admission-policy") {
480
+ return `WorkItemDomainActionAdmissionPolicy '${decision.policyId}' was referenced for WorkItem action admission but not present`;
481
+ }
482
+ return `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries a stale admission policy source ref`;
483
+ }
484
+ function validateWorkItemAdmissionPolicy(policy, decision, proposal) {
485
+ if (policy.actionKinds !== void 0 && !policy.actionKinds.includes(proposal.actionKind)) {
486
+ return {
487
+ code: "work-item-domain-action-admission-policy-mismatch",
488
+ message: `WorkItemDomainActionAdmissionPolicy '${policy.policyId}' does not apply to actionKind '${proposal.actionKind}'`
489
+ };
490
+ }
491
+ if (policy.allowedOutcomes !== void 0 && !policy.allowedOutcomes.includes(decision.outcome)) {
492
+ return {
493
+ code: "unsupported-work-item-domain-action-admission-outcome",
494
+ message: `WorkItemDomainActionAdmissionPolicy '${policy.policyId}' does not allow outcome '${decision.outcome}'`
495
+ };
496
+ }
497
+ return void 0;
498
+ }
499
+ function validateWorkItemAdmissionMergeTarget(state, decision) {
500
+ const hasTargetProposal = decision.targetProposalId !== void 0;
501
+ const hasTargetAdmission = decision.targetAdmissionId !== void 0;
502
+ if (decision.outcome !== "merge") {
503
+ if (hasTargetProposal || hasTargetAdmission) {
504
+ return {
505
+ code: "ambiguous-work-item-domain-action-admission-merge-target",
506
+ message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries a merge target for non-merge outcome '${decision.outcome}'`
507
+ };
508
+ }
509
+ return void 0;
510
+ }
511
+ if (hasTargetProposal === hasTargetAdmission) {
512
+ return {
513
+ code: "ambiguous-work-item-domain-action-admission-merge-target",
514
+ message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' must reference exactly one merge target`
515
+ };
516
+ }
517
+ if (decision.targetProposalId === decision.proposalId) {
518
+ return {
519
+ code: "ambiguous-work-item-domain-action-admission-merge-target",
520
+ message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' cannot merge a proposal into itself`
521
+ };
522
+ }
523
+ if (decision.targetProposalId !== void 0 && !state.proposals.has(decision.targetProposalId)) {
524
+ return {
525
+ code: "unknown-work-item-domain-action-admission-merge-target",
526
+ message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references unknown target proposal '${decision.targetProposalId}'`
527
+ };
528
+ }
529
+ if (decision.targetAdmissionId !== void 0 && !state.admissionsById.has(decision.targetAdmissionId)) {
530
+ return {
531
+ code: "unknown-work-item-domain-action-admission-merge-target",
532
+ message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references unknown target admission '${decision.targetAdmissionId}'`
533
+ };
534
+ }
535
+ return void 0;
536
+ }
537
+ function admissionStateForOutcome(outcome) {
538
+ if (outcome === "admit") return "admitted";
539
+ if (outcome === "reject") return "rejected";
540
+ if (outcome === "defer") return "deferred";
541
+ if (outcome === "merge") return "merged";
542
+ return void 0;
543
+ }
544
+ function workItemAdmissionStatusState(state) {
545
+ if (state === "admitted") return "domain-action-admitted";
546
+ if (state === "rejected") return "domain-action-rejected";
547
+ if (state === "deferred") return "domain-action-deferred";
548
+ return "domain-action-merged";
549
+ }
550
+
551
+ // src/solutions/work-item/actions-shared.ts
552
+ function auditRecord(kind, seq, status) {
553
+ return {
554
+ id: `${kind}:${seq}`,
555
+ kind,
556
+ subjectId: status.workItemId,
557
+ message: status.message,
558
+ issueCode: status.code,
559
+ sourceRefs: status.sourceRefs,
560
+ metadata: {
561
+ statusId: status.statusId,
562
+ state: status.state,
563
+ proposalId: status.proposalId,
564
+ admissionId: status.admissionId,
565
+ actionKind: status.actionKind,
566
+ ...status.metadata ?? {}
567
+ }
568
+ };
569
+ }
570
+ function project(graph, runtime, name, factory, select) {
571
+ return graph.node(
572
+ [runtime],
573
+ (ctx) => {
574
+ for (const raw of depBatch(ctx, 0) ?? []) {
575
+ const selected = select(raw);
576
+ if (selected !== void 0) ctx.down([["DATA", selected]]);
577
+ }
578
+ },
579
+ { name, factory, partial: true, completeWhenDepsComplete: false, errorWhenDepsError: false }
580
+ );
581
+ }
582
+ function dataIssue2(code, message, opts = {}) {
583
+ return {
584
+ kind: "issue",
585
+ code,
586
+ message,
587
+ severity: "error",
588
+ source: "work-item-actions",
589
+ subjectId: opts.subjectId,
590
+ refs: opts.refs?.map((sourceRef) => `${sourceRef.kind}:${sourceRef.id}`),
591
+ metadata: opts.metadata
592
+ };
593
+ }
594
+ function uniqueSourceRefs2(sourceRefs2) {
595
+ const seen = /* @__PURE__ */ new Set();
596
+ const out = [];
597
+ for (const sourceRef of sourceRefs2) {
598
+ const key = `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
599
+ if (seen.has(key)) continue;
600
+ seen.add(key);
601
+ out.push(sourceRef);
602
+ }
603
+ return out;
604
+ }
605
+ function sourceRefs(value) {
606
+ if (!Array.isArray(value)) return void 0;
607
+ return value.filter(
608
+ (item) => isRecord(item) && typeof item.kind === "string" && typeof item.id === "string"
609
+ );
610
+ }
611
+ function numberMetadata(metadata, key) {
612
+ const value = metadata?.[key];
613
+ return typeof value === "number" ? value : void 0;
614
+ }
615
+ function stringMetadata(metadata, key) {
616
+ const value = metadata?.[key];
617
+ return typeof value === "string" ? value : void 0;
618
+ }
619
+ function ref2(kind, id) {
620
+ return { kind, id };
621
+ }
622
+ function recordString(value, key) {
623
+ return isRecord(value) && typeof value[key] === "string" ? value[key] : void 0;
624
+ }
625
+ function isRecord(value) {
626
+ return value !== null && typeof value === "object";
627
+ }
628
+
629
+ // src/solutions/work-item/actions-types.ts
630
+ var patchFieldKeys = /* @__PURE__ */ new Set([
631
+ "summary",
632
+ "detail",
633
+ "detailRefs",
634
+ "kind",
635
+ "priority",
636
+ "tags",
637
+ "owner",
638
+ "assignee",
639
+ "deadlineMs",
640
+ "customFields",
641
+ "sourceRefs",
642
+ "metadata"
643
+ ]);
644
+
645
+ // src/solutions/work-item/scheduling-shared.ts
646
+ function normalizePlanFromUnknown(draft) {
647
+ const verificationPlan = draft.verificationPlan;
648
+ if (verificationPlan !== void 0) {
649
+ if (!isRecord2(verificationPlan) || !Array.isArray(verificationPlan.steps)) {
650
+ return { planId: "malformed", steps: [] };
651
+ }
652
+ return verificationPlan;
653
+ }
654
+ const verificationSteps = draft.verificationSteps;
655
+ if (verificationSteps !== void 0) {
656
+ if (!Array.isArray(verificationSteps)) return { planId: "malformed", steps: [] };
657
+ return { planId: "default", steps: verificationSteps };
658
+ }
659
+ return void 0;
660
+ }
661
+ function isVerificationPlanShape(value) {
662
+ return isRecord2(value) && typeof value.planId === "string" && Array.isArray(value.steps);
663
+ }
664
+ function issue(code, message, workItemId, metadata) {
665
+ return {
666
+ kind: "issue",
667
+ code,
668
+ message,
669
+ severity: "error",
670
+ source: "work-item-scheduling",
671
+ subjectId: workItemId,
672
+ metadata
673
+ };
674
+ }
675
+ function isRecord2(value) {
676
+ return value !== null && typeof value === "object";
677
+ }
678
+
679
+ // src/solutions/work-item/scheduling-validation.ts
680
+ function validateWorkItemDraft(draft, opts = {}) {
681
+ const out = [];
682
+ if (!isRecord2(draft)) {
683
+ return [issue("malformed-draft", "WorkItemDraft must be an object", opts.workItemId)];
684
+ }
685
+ if (typeof draft.summary !== "string") {
686
+ out.push(issue("missing-required-field", "WorkItemDraft.summary is required", opts.workItemId));
687
+ } else if (draft.summary.trim() === "") {
688
+ out.push(issue("missing-required-field", "WorkItemDraft.summary is required", opts.workItemId));
689
+ }
690
+ const criteria = draft.acceptanceCriteria === void 0 || Array.isArray(draft.acceptanceCriteria) ? draft.acceptanceCriteria : void 0;
691
+ if (draft.acceptanceCriteria !== void 0 && criteria === void 0) {
692
+ out.push(
693
+ issue(
694
+ "malformed-draft",
695
+ "WorkItemDraft.acceptanceCriteria must be an array",
696
+ opts.workItemId
697
+ )
698
+ );
699
+ }
700
+ out.push(...validateAcceptanceCriteria(criteria ?? [], opts));
701
+ if (draft.verificationPlan !== void 0 && !isVerificationPlanShape(draft.verificationPlan)) {
702
+ out.push(
703
+ issue("malformed-draft", "WorkItemDraft.verificationPlan is malformed", opts.workItemId)
704
+ );
705
+ }
706
+ if (draft.verificationSteps !== void 0 && !Array.isArray(draft.verificationSteps)) {
707
+ out.push(
708
+ issue("malformed-draft", "WorkItemDraft.verificationSteps must be an array", opts.workItemId)
709
+ );
710
+ }
711
+ const plan = normalizePlanFromUnknown(draft);
712
+ if (plan !== void 0) {
713
+ out.push(...validateVerificationPlan(plan, criteria ?? [], opts));
714
+ }
715
+ return out;
716
+ }
717
+ function validateAcceptanceCriteria(criteria, opts = {}) {
718
+ const out = [];
719
+ const seen = /* @__PURE__ */ new Set();
720
+ for (const criterion of criteria) {
721
+ if (!isRecord2(criterion)) {
722
+ out.push(issue("malformed-draft", "AcceptanceCriterion must be an object", opts.workItemId));
723
+ continue;
724
+ }
725
+ if (typeof criterion.criterionId !== "string" || criterion.criterionId === "") {
726
+ out.push(
727
+ issue(
728
+ "missing-required-field",
729
+ "AcceptanceCriterion.criterionId is required",
730
+ opts.workItemId
731
+ )
732
+ );
733
+ continue;
734
+ }
735
+ if (seen.has(criterion.criterionId)) {
736
+ out.push(
737
+ issue(
738
+ "duplicate-id",
739
+ `Duplicate acceptance criterion id '${criterion.criterionId}'`,
740
+ opts.workItemId,
741
+ { criterionId: criterion.criterionId }
742
+ )
743
+ );
744
+ }
745
+ seen.add(criterion.criterionId);
746
+ if (typeof criterion.statement !== "string" || criterion.statement.trim() === "") {
747
+ out.push(
748
+ issue(
749
+ "missing-required-field",
750
+ "AcceptanceCriterion.statement is required",
751
+ opts.workItemId,
752
+ { criterionId: criterion.criterionId }
753
+ )
754
+ );
755
+ }
756
+ }
757
+ return out;
758
+ }
759
+ function validateVerificationPlan(plan, criteria = [], opts = {}) {
760
+ const out = [];
761
+ if (!isRecord2(plan) || !Array.isArray(plan.steps)) {
762
+ return [issue("malformed-draft", "VerificationPlan.steps must be an array", opts.workItemId)];
763
+ }
764
+ const criterionIds = new Set(criteria.map((criterion) => criterion.criterionId));
765
+ const stepIds = /* @__PURE__ */ new Set();
766
+ const modes = new Set(opts.allowedModes ?? ["auto", "manual", "hybrid"]);
767
+ const effectKinds = new Set(opts.allowedEffectKinds ?? ["verification"]);
768
+ for (const step of plan.steps) {
769
+ if (!isRecord2(step)) {
770
+ out.push(issue("malformed-draft", "VerificationStep must be an object", opts.workItemId));
771
+ continue;
772
+ }
773
+ if (typeof step.stepId !== "string" || step.stepId === "") {
774
+ out.push(
775
+ issue("missing-required-field", "VerificationStep.stepId is required", opts.workItemId)
776
+ );
777
+ continue;
778
+ }
779
+ if (stepIds.has(step.stepId)) {
780
+ out.push(
781
+ issue("duplicate-id", `Duplicate verification step id '${step.stepId}'`, opts.workItemId, {
782
+ stepId: step.stepId
783
+ })
784
+ );
785
+ }
786
+ stepIds.add(step.stepId);
787
+ if (typeof step.mode !== "string" || !modes.has(step.mode)) {
788
+ out.push(
789
+ issue(
790
+ "unsupported-mode",
791
+ `Unsupported verification step mode '${step.mode}'`,
792
+ opts.workItemId,
793
+ { stepId: step.stepId }
794
+ )
795
+ );
796
+ }
797
+ if (step.effectKind !== void 0 && (typeof step.effectKind !== "string" || !effectKinds.has(step.effectKind))) {
798
+ out.push(
799
+ issue(
800
+ "unsupported-effect-kind",
801
+ `Unsupported verification effect kind '${step.effectKind}'`,
802
+ opts.workItemId,
803
+ { stepId: step.stepId }
804
+ )
805
+ );
806
+ }
807
+ const verifiesCriteriaIds = Array.isArray(step.verifiesCriteriaIds) ? step.verifiesCriteriaIds : [];
808
+ for (const criterionId of verifiesCriteriaIds) {
809
+ if (!criterionIds.has(criterionId)) {
810
+ out.push(
811
+ issue("dangling-ref", `Unknown acceptance criterion '${criterionId}'`, opts.workItemId, {
812
+ stepId: step.stepId,
813
+ criterionId
814
+ })
815
+ );
816
+ }
817
+ }
818
+ }
819
+ for (const step of plan.steps) {
820
+ if (!isRecord2(step) || typeof step.stepId !== "string") continue;
821
+ const dependsOnStepIds = Array.isArray(step.dependsOnStepIds) ? step.dependsOnStepIds : [];
822
+ for (const depId of dependsOnStepIds) {
823
+ if (!stepIds.has(depId)) {
824
+ out.push(
825
+ issue("dangling-ref", `Unknown verification dependency '${depId}'`, opts.workItemId, {
826
+ stepId: step.stepId
827
+ })
828
+ );
829
+ }
830
+ }
831
+ }
832
+ const cycle = findCycle(
833
+ plan.steps.filter(
834
+ (step) => isRecord2(step) && typeof step.stepId === "string" && Array.isArray(step.dependsOnStepIds)
835
+ )
836
+ );
837
+ if (cycle !== void 0) {
838
+ out.push(
839
+ issue(
840
+ "cyclic-dependency",
841
+ `Verification step cycle detected: ${cycle.join(" -> ")}`,
842
+ opts.workItemId,
843
+ { stepId: cycle[0] }
844
+ )
845
+ );
846
+ }
847
+ return out;
848
+ }
849
+ function findCycle(steps) {
850
+ const byId = new Map(steps.map((step) => [step.stepId, step.dependsOnStepIds ?? []]));
851
+ const visiting = /* @__PURE__ */ new Set();
852
+ const visited = /* @__PURE__ */ new Set();
853
+ const stack = [];
854
+ const visit = (id) => {
855
+ if (visiting.has(id)) return [...stack.slice(stack.indexOf(id)), id];
856
+ if (visited.has(id)) return void 0;
857
+ visiting.add(id);
858
+ stack.push(id);
859
+ for (const dep of byId.get(id) ?? []) {
860
+ if (!byId.has(dep)) continue;
861
+ const cycle = visit(dep);
862
+ if (cycle !== void 0) return cycle;
863
+ }
864
+ stack.pop();
865
+ visiting.delete(id);
866
+ visited.add(id);
867
+ return void 0;
868
+ };
869
+ for (const step of steps) {
870
+ const cycle = visit(step.stepId);
871
+ if (cycle !== void 0) return cycle;
872
+ }
873
+ return void 0;
874
+ }
875
+
876
+ // src/solutions/work-item/actions-application.ts
877
+ function workItemDomainActionApplicationProjector(graph, opts) {
878
+ const name = opts.name ?? "workItemDomainActionApplication";
879
+ const deps = opts.applyPolicies === void 0 ? [opts.proposals, opts.admissions, opts.workItems] : [opts.proposals, opts.admissions, opts.workItems, opts.applyPolicies];
880
+ const runtime = graph.node(
881
+ deps,
882
+ (ctx) => {
883
+ const state = ctx.state.get() ?? {
884
+ proposals: /* @__PURE__ */ new Map(),
885
+ admissions: /* @__PURE__ */ new Map(),
886
+ workItems: /* @__PURE__ */ new Map(),
887
+ policies: /* @__PURE__ */ new Map(),
888
+ appliedAdmissions: /* @__PURE__ */ new Set(),
889
+ emittedFactIds: /* @__PURE__ */ new Set(),
890
+ issueKeys: /* @__PURE__ */ new Set(),
891
+ statusSeq: 0,
892
+ auditSeq: 0
893
+ };
894
+ for (const raw of depBatch(ctx, 0) ?? []) {
895
+ const proposal = raw;
896
+ if (state.proposals.has(proposal.proposalId)) {
897
+ emitApplicationIssue(
898
+ ctx,
899
+ state,
900
+ `duplicate-proposal:${proposal.proposalId}`,
901
+ "duplicate-suppressed",
902
+ `Duplicate WorkItem domain action proposal '${proposal.proposalId}' suppressed`,
903
+ proposal.workItemId,
904
+ proposal.sourceRefs
905
+ );
906
+ continue;
907
+ }
908
+ state.proposals.set(proposal.proposalId, proposal);
909
+ }
910
+ for (const raw of depBatch(ctx, 2) ?? []) {
911
+ const workItem = raw;
912
+ state.workItems.set(workItem.workItemId, workItem);
913
+ }
914
+ if (opts.applyPolicies !== void 0) {
915
+ for (const raw of depBatch(ctx, 3) ?? []) {
916
+ const policy = raw;
917
+ state.policies.set(policy.policyId, policy);
918
+ }
919
+ }
920
+ for (const raw of depBatch(ctx, 1) ?? []) {
921
+ const admission = raw;
922
+ if (state.admissions.has(admission.admissionId)) {
923
+ emitApplicationIssue(
924
+ ctx,
925
+ state,
926
+ `duplicate-admission:${admission.admissionId}`,
927
+ "duplicate-suppressed",
928
+ `Duplicate WorkItem domain action admission '${admission.admissionId}' suppressed`,
929
+ admission.workItemId,
930
+ admissionRefs(admission)
931
+ );
932
+ continue;
933
+ }
934
+ state.admissions.set(admission.admissionId, admission);
935
+ }
936
+ for (const admission of state.admissions.values()) applyAdmission(ctx, state, admission);
937
+ ctx.state.set(state);
938
+ },
939
+ {
940
+ name: `${name}/runtime`,
941
+ factory: "workItemDomainActionApplicationProjector",
942
+ partial: true,
943
+ completeWhenDepsComplete: false,
944
+ errorWhenDepsError: false
945
+ }
946
+ );
947
+ return {
948
+ authoringFacts: project(
949
+ graph,
950
+ runtime,
951
+ `${name}/authoringFacts`,
952
+ "workItemDomainActionAuthoringFacts",
953
+ (fact) => fact.kind === "authoring-fact" ? fact.value : void 0
954
+ ),
955
+ applications: project(
956
+ graph,
957
+ runtime,
958
+ `${name}/applications`,
959
+ "workItemDomainActionApplications",
960
+ (fact) => fact.kind === "application" ? fact.value : void 0
961
+ ),
962
+ status: project(
963
+ graph,
964
+ runtime,
965
+ `${name}/status`,
966
+ "workItemDomainActionStatus",
967
+ (fact) => fact.kind === "status" ? fact.value : void 0
968
+ ),
969
+ issues: project(
970
+ graph,
971
+ runtime,
972
+ `${name}/issues`,
973
+ "workItemDomainActionIssues",
974
+ (fact) => fact.kind === "issue" ? fact.value : void 0
975
+ ),
976
+ audit: project(
977
+ graph,
978
+ runtime,
979
+ `${name}/audit`,
980
+ "workItemDomainActionAudit",
981
+ (fact) => fact.kind === "audit" ? fact.value : void 0
982
+ )
983
+ };
984
+ }
985
+ function applyAdmission(ctx, state, admission) {
986
+ if (state.appliedAdmissions.has(admission.admissionId)) return;
987
+ const proposal = state.proposals.get(admission.proposalId);
988
+ if (proposal === void 0) {
989
+ emitApplicationIssue(
990
+ ctx,
991
+ state,
992
+ `missing-proposal:${admission.admissionId}:${admission.proposalId}`,
993
+ "dangling-ref",
994
+ `Admission '${admission.admissionId}' cannot apply without proposal '${admission.proposalId}'`,
995
+ admission.workItemId,
996
+ admissionRefs(admission)
997
+ );
998
+ return;
999
+ }
1000
+ if (admission.state !== "admitted") {
1001
+ state.appliedAdmissions.add(admission.admissionId);
1002
+ emitApplication(ctx, state, admission, proposal, admission.state, []);
1003
+ return;
1004
+ }
1005
+ const mismatch = admissionProposalMismatch(admission, proposal);
1006
+ if (mismatch !== void 0) {
1007
+ state.appliedAdmissions.add(admission.admissionId);
1008
+ emitApplicationIssue(
1009
+ ctx,
1010
+ state,
1011
+ `admission-proposal-mismatch:${admission.admissionId}:${mismatch.field}`,
1012
+ "dangling-ref",
1013
+ mismatch.message,
1014
+ admission.workItemId,
1015
+ admissionRefs(admission, proposal),
1016
+ {
1017
+ field: mismatch.field,
1018
+ admissionValue: mismatch.admissionValue,
1019
+ proposalValue: mismatch.proposalValue
1020
+ }
1021
+ );
1022
+ emitApplication(ctx, state, admission, proposal, "rejected", [], {
1023
+ code: "dangling-ref",
1024
+ message: mismatch.message
1025
+ });
1026
+ return;
1027
+ }
1028
+ const workItem = state.workItems.get(admission.workItemId);
1029
+ if (workItem === void 0) {
1030
+ emitApplicationIssue(
1031
+ ctx,
1032
+ state,
1033
+ `missing-work-item:${admission.admissionId}:${admission.workItemId}`,
1034
+ "dangling-ref",
1035
+ `Admission '${admission.admissionId}' references unknown WorkItem '${admission.workItemId}'`,
1036
+ admission.workItemId,
1037
+ admissionRefs(admission, proposal)
1038
+ );
1039
+ return;
1040
+ }
1041
+ const metadataConflict = conflictingApplicationMetadata(proposal, admission);
1042
+ if (metadataConflict !== void 0) {
1043
+ state.appliedAdmissions.add(admission.admissionId);
1044
+ emitApplicationIssue(
1045
+ ctx,
1046
+ state,
1047
+ `metadata-conflict:${admission.admissionId}:${metadataConflict.field}`,
1048
+ metadataConflict.code,
1049
+ metadataConflict.message,
1050
+ admission.workItemId,
1051
+ admissionRefs(admission, proposal),
1052
+ {
1053
+ field: metadataConflict.field,
1054
+ admissionValue: metadataConflict.admissionValue,
1055
+ proposalValue: metadataConflict.proposalValue
1056
+ }
1057
+ );
1058
+ emitApplication(ctx, state, admission, proposal, "rejected", [], {
1059
+ code: metadataConflict.code,
1060
+ message: metadataConflict.message
1061
+ });
1062
+ return;
1063
+ }
1064
+ const stale = staleRevision(proposal, admission, workItem);
1065
+ if (stale !== void 0) {
1066
+ state.appliedAdmissions.add(admission.admissionId);
1067
+ emitApplicationIssue(
1068
+ ctx,
1069
+ state,
1070
+ `stale:${admission.admissionId}:${stale.kind}:${stale.expected}:${stale.current}`,
1071
+ stale.kind,
1072
+ `Admission '${admission.admissionId}' targets stale WorkItem revision`,
1073
+ admission.workItemId,
1074
+ admissionRefs(admission, proposal),
1075
+ { expected: stale.expected, current: stale.current }
1076
+ );
1077
+ emitApplication(ctx, state, admission, proposal, "rejected", [], {
1078
+ code: stale.kind,
1079
+ message: "Stale WorkItem revision"
1080
+ });
1081
+ return;
1082
+ }
1083
+ const policyResult = selectApplyPolicy(state, proposal, admission);
1084
+ if (typeof policyResult === "string") {
1085
+ emitApplicationIssue(
1086
+ ctx,
1087
+ state,
1088
+ `policy:${admission.admissionId}:${policyResult}`,
1089
+ policyResult,
1090
+ applyPolicyMessage(policyResult, proposal, admission),
1091
+ admission.workItemId,
1092
+ admissionRefs(admission, proposal)
1093
+ );
1094
+ return;
1095
+ }
1096
+ const output = lowerAction(ctx, state, workItem, proposal, admission, policyResult);
1097
+ if (output === void 0) {
1098
+ state.appliedAdmissions.add(admission.admissionId);
1099
+ emitApplication(ctx, state, admission, proposal, "rejected", [], {
1100
+ code: "invalid-action",
1101
+ message: "WorkItem domain action application rejected; see emitted issues",
1102
+ policyId: policyResult.policyId
1103
+ });
1104
+ return;
1105
+ }
1106
+ const duplicateFactId = firstDuplicateFactId(state, output.facts);
1107
+ if (duplicateFactId !== void 0) {
1108
+ state.appliedAdmissions.add(admission.admissionId);
1109
+ emitApplicationIssue(
1110
+ ctx,
1111
+ state,
1112
+ `duplicate-authoring-fact:${admission.admissionId}:${duplicateFactId}`,
1113
+ "duplicate-suppressed",
1114
+ `WorkItem domain action application '${admission.admissionId}' would duplicate authoring fact '${duplicateFactId}'`,
1115
+ admission.workItemId,
1116
+ admissionRefs(admission, proposal, policyResult),
1117
+ { eventId: duplicateFactId }
1118
+ );
1119
+ emitApplication(ctx, state, admission, proposal, "duplicate", [], {
1120
+ code: "duplicate-suppressed",
1121
+ message: "Duplicate WorkItem authoring fact suppressed atomically",
1122
+ policyId: policyResult.policyId
1123
+ });
1124
+ return;
1125
+ }
1126
+ state.appliedAdmissions.add(admission.admissionId);
1127
+ for (const fact of output.facts) claimFactId(state, fact.eventId);
1128
+ for (const fact of output.facts) emitApplicationFact(ctx, "authoring-fact", fact);
1129
+ emitApplication(ctx, state, admission, proposal, output.state, output.facts, {
1130
+ code: output.code,
1131
+ message: output.message,
1132
+ policyId: policyResult.policyId
1133
+ });
1134
+ }
1135
+ function lowerAction(ctx, state, workItem, proposal, admission, policy) {
1136
+ if (!policyAllowsAction(policy, proposal.actionKind)) {
1137
+ emitApplicationIssue(
1138
+ ctx,
1139
+ state,
1140
+ `policy-action:${admission.admissionId}:${policy.policyId}:${proposal.actionKind}`,
1141
+ "policy-mismatch",
1142
+ `Apply policy '${policy.policyId}' does not allow actionKind '${proposal.actionKind}'`,
1143
+ proposal.workItemId,
1144
+ admissionRefs(admission, proposal, policy)
1145
+ );
1146
+ return { state: "policy-rejected", facts: [], code: "policy-mismatch" };
1147
+ }
1148
+ if (proposal.actionKind === "patch") {
1149
+ const lowered = lowerPatchAction(ctx, state, workItem, proposal, admission, policy);
1150
+ if (lowered === void 0) return void 0;
1151
+ return { state: "applied", facts: lowered };
1152
+ }
1153
+ if (proposal.actionKind === "mark-verified" || proposal.actionKind === "require-review") {
1154
+ return {
1155
+ state: "proposal-only",
1156
+ facts: [],
1157
+ code: "domain-fact-unimplemented",
1158
+ message: `Action '${proposal.actionKind}' recorded as visible application status only; no WorkItem domain mutation fact was emitted`
1159
+ };
1160
+ }
1161
+ if (proposal.actionKind === "spawn-proposed" || proposal.actionKind === "spawn-child") {
1162
+ return lowerSpawnAction(ctx, state, proposal, admission, policy);
1163
+ }
1164
+ emitApplicationIssue(
1165
+ ctx,
1166
+ state,
1167
+ `unsupported-action:${admission.admissionId}:${proposal.actionKind}`,
1168
+ "unsupported-effect-kind",
1169
+ `Unsupported WorkItem domain actionKind '${proposal.actionKind}'`,
1170
+ proposal.workItemId,
1171
+ admissionRefs(admission, proposal, policy)
1172
+ );
1173
+ return { state: "rejected", facts: [], code: "unsupported-effect-kind" };
1174
+ }
1175
+ function lowerPatchAction(ctx, state, workItem, proposal, admission, policy) {
1176
+ const payload = normalizePatchPayload(proposal.payload);
1177
+ if (typeof payload === "string") {
1178
+ emitApplicationIssue(
1179
+ ctx,
1180
+ state,
1181
+ `invalid-patch:${admission.admissionId}`,
1182
+ "invalid-patch",
1183
+ payload,
1184
+ proposal.workItemId,
1185
+ admissionRefs(admission, proposal, policy)
1186
+ );
1187
+ return void 0;
1188
+ }
1189
+ const splitPayload = splitDedicatedPatchFields(payload, workItem);
1190
+ const facts = [];
1191
+ if (splitPayload.patch !== void 0) {
1192
+ const invalid = invalidPatchKeys(splitPayload.patch, policy);
1193
+ if (invalid.length > 0) {
1194
+ emitApplicationIssue(
1195
+ ctx,
1196
+ state,
1197
+ `invalid-patch-fields:${admission.admissionId}:${invalid.join(",")}`,
1198
+ "invalid-patch",
1199
+ `Patch action uses unsupported fields: ${invalid.join(", ")}`,
1200
+ proposal.workItemId,
1201
+ admissionRefs(admission, proposal, policy),
1202
+ { invalidFields: invalid }
1203
+ );
1204
+ return void 0;
1205
+ }
1206
+ facts.push({
1207
+ kind: "work-item-patched",
1208
+ eventId: splitPayload.eventId ?? `${admission.admissionId}:work-item-patched`,
1209
+ workItemId: workItem.workItemId,
1210
+ patch: splitPayload.patch,
1211
+ executionRelevantFields: splitPayload.executionRelevantFields ?? policy.patch?.executionRelevantFields,
1212
+ authorId: splitPayload.authorId,
1213
+ sourceRefs: actionSourceRefs(admission, proposal, policy),
1214
+ metadata: { ...splitPayload.metadata ?? {}, actionKind: proposal.actionKind }
1215
+ });
1216
+ }
1217
+ if (splitPayload.acceptanceCriteria !== void 0) {
1218
+ if (!allowsAcceptanceCriteria(policy)) {
1219
+ emitApplicationIssue(
1220
+ ctx,
1221
+ state,
1222
+ `ac-policy:${admission.admissionId}`,
1223
+ "policy-mismatch",
1224
+ `Apply policy '${policy.policyId}' does not allow acceptance criteria changes`,
1225
+ proposal.workItemId,
1226
+ admissionRefs(admission, proposal, policy)
1227
+ );
1228
+ return void 0;
1229
+ }
1230
+ const issues = validateAcceptanceCriteria(splitPayload.acceptanceCriteria, {
1231
+ workItemId: workItem.workItemId
1232
+ });
1233
+ if (issues.length > 0) {
1234
+ for (const item of issues) emitApplicationFact(ctx, "issue", item);
1235
+ emitApplicationStatus(ctx, state, {
1236
+ state: "rejected",
1237
+ code: issues[0]?.code,
1238
+ message: issues[0]?.message,
1239
+ workItemId: workItem.workItemId,
1240
+ proposalId: proposal.proposalId,
1241
+ admissionId: admission.admissionId,
1242
+ actionKind: proposal.actionKind,
1243
+ sourceRefs: admissionRefs(admission, proposal, policy)
1244
+ });
1245
+ return void 0;
1246
+ }
1247
+ facts.push({
1248
+ kind: "acceptance-criteria-changed",
1249
+ eventId: `${admission.admissionId}:acceptance-criteria-changed`,
1250
+ workItemId: workItem.workItemId,
1251
+ acceptanceCriteria: splitPayload.acceptanceCriteria,
1252
+ authorId: splitPayload.authorId,
1253
+ sourceRefs: actionSourceRefs(admission, proposal, policy),
1254
+ metadata: { ...splitPayload.metadata ?? {}, actionKind: proposal.actionKind }
1255
+ });
1256
+ }
1257
+ if (splitPayload.verificationPlan !== void 0) {
1258
+ if (!allowsVerificationPlan(policy)) {
1259
+ emitApplicationIssue(
1260
+ ctx,
1261
+ state,
1262
+ `plan-policy:${admission.admissionId}`,
1263
+ "policy-mismatch",
1264
+ `Apply policy '${policy.policyId}' does not allow verification plan changes`,
1265
+ proposal.workItemId,
1266
+ admissionRefs(admission, proposal, policy)
1267
+ );
1268
+ return void 0;
1269
+ }
1270
+ const issues = validateVerificationPlan(
1271
+ splitPayload.verificationPlan,
1272
+ splitPayload.acceptanceCriteria ?? workItem.acceptanceCriteria ?? [],
1273
+ { workItemId: workItem.workItemId }
1274
+ );
1275
+ if (issues.length > 0) {
1276
+ for (const item of issues) emitApplicationFact(ctx, "issue", item);
1277
+ emitApplicationStatus(ctx, state, {
1278
+ state: "rejected",
1279
+ code: issues[0]?.code,
1280
+ message: issues[0]?.message,
1281
+ workItemId: workItem.workItemId,
1282
+ proposalId: proposal.proposalId,
1283
+ admissionId: admission.admissionId,
1284
+ actionKind: proposal.actionKind,
1285
+ sourceRefs: admissionRefs(admission, proposal, policy)
1286
+ });
1287
+ return void 0;
1288
+ }
1289
+ facts.push({
1290
+ kind: "verification-plan-changed",
1291
+ eventId: `${admission.admissionId}:verification-plan-changed`,
1292
+ workItemId: workItem.workItemId,
1293
+ verificationPlan: splitPayload.verificationPlan,
1294
+ authorId: splitPayload.authorId,
1295
+ sourceRefs: actionSourceRefs(admission, proposal, policy),
1296
+ metadata: { ...splitPayload.metadata ?? {}, actionKind: proposal.actionKind }
1297
+ });
1298
+ }
1299
+ if (facts.length === 0) {
1300
+ emitApplicationIssue(
1301
+ ctx,
1302
+ state,
1303
+ `empty-patch:${admission.admissionId}`,
1304
+ "invalid-patch",
1305
+ "Patch action payload did not contain patch, acceptanceCriteria, or verificationPlan",
1306
+ proposal.workItemId,
1307
+ admissionRefs(admission, proposal, policy)
1308
+ );
1309
+ return void 0;
1310
+ }
1311
+ return facts;
1312
+ }
1313
+ function lowerSpawnAction(ctx, state, proposal, admission, policy) {
1314
+ if (policy.spawn?.create !== true) {
1315
+ return {
1316
+ state: "proposal-only",
1317
+ facts: [],
1318
+ message: "Spawn action remains proposal/admission only without explicit create policy"
1319
+ };
1320
+ }
1321
+ const policyIssue = validateSpawnCreatePolicy(policy, proposal);
1322
+ if (policyIssue !== void 0) {
1323
+ emitApplicationIssue(
1324
+ ctx,
1325
+ state,
1326
+ `spawn-create-policy:${admission.admissionId}:${policy.policyId}:${policyIssue.field}`,
1327
+ "policy-mismatch",
1328
+ policyIssue.message,
1329
+ proposal.workItemId,
1330
+ admissionRefs(admission, proposal, policy),
1331
+ { field: policyIssue.field }
1332
+ );
1333
+ return {
1334
+ state: "policy-rejected",
1335
+ facts: [],
1336
+ code: "policy-mismatch",
1337
+ message: policyIssue.message
1338
+ };
1339
+ }
1340
+ const payload = normalizeSpawnPayload(proposal.payload);
1341
+ if (typeof payload === "string") {
1342
+ emitApplicationIssue(
1343
+ ctx,
1344
+ state,
1345
+ `invalid-spawn-payload:${admission.admissionId}`,
1346
+ "invalid-patch",
1347
+ payload,
1348
+ proposal.workItemId,
1349
+ admissionRefs(admission, proposal, policy)
1350
+ );
1351
+ return { state: "rejected", facts: [], code: "invalid-patch", message: payload };
1352
+ }
1353
+ const childWorkItemId = payload.childWorkItemId ?? payload.workItemId ?? policy.spawn.childWorkItemId ?? (policy.spawn.childIdPrefix === void 0 ? void 0 : `${policy.spawn.childIdPrefix}${admission.admissionId}`);
1354
+ if (childWorkItemId === void 0 || childWorkItemId.trim() === "") {
1355
+ const message = "Spawn create action requires a childWorkItemId or create policy child id";
1356
+ emitApplicationIssue(
1357
+ ctx,
1358
+ state,
1359
+ `missing-spawn-child-id:${admission.admissionId}`,
1360
+ "missing-required-field",
1361
+ message,
1362
+ proposal.workItemId,
1363
+ admissionRefs(admission, proposal, policy)
1364
+ );
1365
+ return { state: "rejected", facts: [], code: "missing-required-field", message };
1366
+ }
1367
+ if (state.workItems.has(childWorkItemId)) {
1368
+ const message = `Spawn create action would duplicate WorkItem '${childWorkItemId}'`;
1369
+ emitApplicationIssue(
1370
+ ctx,
1371
+ state,
1372
+ `duplicate-spawn-child:${admission.admissionId}:${childWorkItemId}`,
1373
+ "duplicate-id",
1374
+ message,
1375
+ childWorkItemId,
1376
+ admissionRefs(admission, proposal, policy)
1377
+ );
1378
+ return { state: "duplicate", facts: [], code: "duplicate-id", message };
1379
+ }
1380
+ if (payload.draft === void 0) {
1381
+ const message = "Spawn create action requires a draft payload";
1382
+ emitApplicationIssue(
1383
+ ctx,
1384
+ state,
1385
+ `missing-spawn-draft:${admission.admissionId}`,
1386
+ "missing-required-field",
1387
+ message,
1388
+ childWorkItemId,
1389
+ admissionRefs(admission, proposal, policy)
1390
+ );
1391
+ return { state: "rejected", facts: [], code: "missing-required-field", message };
1392
+ }
1393
+ const issues = validateWorkItemDraft(payload.draft, { workItemId: childWorkItemId });
1394
+ if (issues.length > 0) {
1395
+ for (const item of issues) emitApplicationFact(ctx, "issue", item);
1396
+ return {
1397
+ state: "rejected",
1398
+ facts: [],
1399
+ code: issues[0]?.code,
1400
+ message: issues[0]?.message
1401
+ };
1402
+ }
1403
+ const metadata = {
1404
+ ...payload.metadata ?? {},
1405
+ actionKind: proposal.actionKind,
1406
+ parentWorkItemId: policy.spawn.linkParent === true ? proposal.workItemId : void 0,
1407
+ sourceProposalId: proposal.proposalId,
1408
+ idempotencyKey: payload.idempotencyKey ?? policy.spawn.idempotencyKey
1409
+ };
1410
+ const created = {
1411
+ kind: "work-item-created",
1412
+ eventId: payload.eventId ?? `${admission.admissionId}:work-item-created:${childWorkItemId}`,
1413
+ workItemId: childWorkItemId,
1414
+ draft: payload.draft,
1415
+ authorId: payload.authorId,
1416
+ sourceRefs: actionSourceRefs(admission, proposal, policy),
1417
+ metadata
1418
+ };
1419
+ return { state: "applied", facts: [created] };
1420
+ }
1421
+ function validateSpawnCreatePolicy(policy, proposal) {
1422
+ if (policy.spawn?.idempotencyKey === void 0 || policy.spawn.idempotencyKey.trim() === "") {
1423
+ return {
1424
+ field: "idempotencyKey",
1425
+ message: `Spawn create policy '${policy.policyId}' requires an idempotencyKey`
1426
+ };
1427
+ }
1428
+ if (policy.spawn.maxChildrenPerAdmission === void 0 || policy.spawn.maxChildrenPerAdmission < 1) {
1429
+ return {
1430
+ field: "maxChildrenPerAdmission",
1431
+ message: `Spawn create policy '${policy.policyId}' requires maxChildrenPerAdmission >= 1`
1432
+ };
1433
+ }
1434
+ if (proposal.actionKind === "spawn-child" && policy.spawn.linkParent !== true) {
1435
+ return {
1436
+ field: "linkParent",
1437
+ message: `Spawn child create policy '${policy.policyId}' requires linkParent: true`
1438
+ };
1439
+ }
1440
+ return void 0;
1441
+ }
1442
+ function normalizeSpawnPayload(payload) {
1443
+ if (!isRecord(payload)) return "Spawn action payload must be an object";
1444
+ if ("draft" in payload && payload.draft !== void 0 && !isRecord(payload.draft)) {
1445
+ return "Spawn action payload.draft must be an object";
1446
+ }
1447
+ if ("metadata" in payload && payload.metadata !== void 0 && !isRecord(payload.metadata)) {
1448
+ return "Spawn action payload.metadata must be an object";
1449
+ }
1450
+ return payload;
1451
+ }
1452
+ function normalizePatchPayload(payload) {
1453
+ if (!isRecord(payload)) return "Patch action payload must be an object";
1454
+ if ("patch" in payload || "acceptanceCriteria" in payload || "verificationPlan" in payload || "executionRelevantFields" in payload) {
1455
+ if ("patch" in payload && payload.patch !== void 0 && !isRecord(payload.patch))
1456
+ return "Patch action payload.patch must be an object";
1457
+ if ("acceptanceCriteria" in payload && payload.acceptanceCriteria !== void 0 && !Array.isArray(payload.acceptanceCriteria))
1458
+ return "Patch action payload.acceptanceCriteria must be an array";
1459
+ if ("verificationPlan" in payload && payload.verificationPlan !== void 0 && !isRecord(payload.verificationPlan))
1460
+ return "Patch action payload.verificationPlan must be an object";
1461
+ const inlinePatch = inlinePatchFields(payload);
1462
+ const explicitPatch = isRecord(payload.patch) ? payload.patch : void 0;
1463
+ const patch = explicitPatch === void 0 ? inlinePatch : { ...inlinePatch, ...explicitPatch };
1464
+ return {
1465
+ ...payload,
1466
+ patch: Object.keys(patch).length === 0 ? void 0 : patch
1467
+ };
1468
+ }
1469
+ return { patch: payload };
1470
+ }
1471
+ function inlinePatchFields(payload) {
1472
+ const patch = {};
1473
+ for (const [key, value] of Object.entries(payload)) {
1474
+ if (key === "metadata") continue;
1475
+ if (patchFieldKeys.has(key)) patch[key] = value;
1476
+ }
1477
+ return patch;
1478
+ }
1479
+ function splitDedicatedPatchFields(payload, workItem) {
1480
+ if (!isRecord(payload.patch)) return payload;
1481
+ const patchRecord = payload.patch;
1482
+ const patch = {};
1483
+ for (const [key, value] of Object.entries(patchRecord)) {
1484
+ if (key === "acceptanceCriteria" || key === "verificationPlan" || key === "verificationSteps")
1485
+ continue;
1486
+ patch[key] = value;
1487
+ }
1488
+ const acceptanceCriteria = payload.acceptanceCriteria ?? (Array.isArray(patchRecord.acceptanceCriteria) ? patchRecord.acceptanceCriteria : void 0);
1489
+ const verificationPlan = payload.verificationPlan ?? (isRecord(patchRecord.verificationPlan) ? patchRecord.verificationPlan : Array.isArray(patchRecord.verificationSteps) ? {
1490
+ ...workItem.verificationPlan ?? { planId: "default" },
1491
+ steps: patchRecord.verificationSteps
1492
+ } : void 0);
1493
+ return {
1494
+ ...payload,
1495
+ patch: Object.keys(patch).length === 0 ? void 0 : patch,
1496
+ acceptanceCriteria,
1497
+ verificationPlan
1498
+ };
1499
+ }
1500
+ function invalidPatchKeys(patch, policy) {
1501
+ const allowed = new Set(policy.patch?.allowedFields ?? Array.from(patchFieldKeys));
1502
+ return Object.keys(patch).filter((key) => !patchFieldKeys.has(key) || !allowed.has(key));
1503
+ }
1504
+ function allowsAcceptanceCriteria(policy) {
1505
+ if (policy.patch?.allowAcceptanceCriteria === false) return false;
1506
+ const allowed = policy.patch?.allowedFields;
1507
+ return allowed === void 0 || allowed.includes("acceptanceCriteria") || policy.patch?.allowAcceptanceCriteria === true;
1508
+ }
1509
+ function allowsVerificationPlan(policy) {
1510
+ if (policy.patch?.allowVerificationPlan === false) return false;
1511
+ const allowed = policy.patch?.allowedFields;
1512
+ return allowed === void 0 || allowed.includes("verificationPlan") || allowed.includes("verificationSteps") || policy.patch?.allowVerificationPlan === true;
1513
+ }
1514
+ function selectApplyPolicy(state, proposal, admission) {
1515
+ const explicitId = explicitApplyPolicyId(proposal, admission);
1516
+ if (explicitId !== void 0)
1517
+ return state.policies.get(explicitId) ?? "unknown-work-item-domain-action-apply-policy";
1518
+ const matching = Array.from(state.policies.values()).filter(
1519
+ (policy) => policyAllowsAction(policy, proposal.actionKind)
1520
+ );
1521
+ if (matching.length === 0) return "missing-policy";
1522
+ if (matching.length > 1) return "policy-mismatch";
1523
+ return matching[0];
1524
+ }
1525
+ function explicitApplyPolicyId(proposal, admission) {
1526
+ const metadataPolicy = stringMetadata(admission.metadata, "applyPolicyId") ?? stringMetadata(proposal.metadata, "applyPolicyId");
1527
+ if (metadataPolicy !== void 0) return metadataPolicy;
1528
+ return [...admission.sourceRefs ?? [], ...proposal.sourceRefs ?? []].find(
1529
+ (sourceRef) => sourceRef.kind === "work-item-domain-action-apply-policy"
1530
+ )?.id;
1531
+ }
1532
+ function policyAllowsAction(policy, actionKind) {
1533
+ return policy.actionKinds === void 0 || policy.actionKinds.includes(actionKind);
1534
+ }
1535
+ function admissionProposalMismatch(admission, proposal) {
1536
+ if (admission.workItemId !== proposal.workItemId)
1537
+ return {
1538
+ field: "workItemId",
1539
+ admissionValue: admission.workItemId,
1540
+ proposalValue: proposal.workItemId,
1541
+ message: `Admission '${admission.admissionId}' workItemId does not match proposal '${proposal.proposalId}'`
1542
+ };
1543
+ if (admission.actionKind !== proposal.actionKind)
1544
+ return {
1545
+ field: "actionKind",
1546
+ admissionValue: admission.actionKind,
1547
+ proposalValue: proposal.actionKind,
1548
+ message: `Admission '${admission.admissionId}' actionKind does not match proposal '${proposal.proposalId}'`
1549
+ };
1550
+ return void 0;
1551
+ }
1552
+ function conflictingApplicationMetadata(proposal, admission) {
1553
+ const authoringRevision = conflictingMetadataNumber(proposal, admission, "authoringRevision");
1554
+ if (authoringRevision !== void 0)
1555
+ return {
1556
+ field: "authoringRevision",
1557
+ code: "stale-revision",
1558
+ ...authoringRevision,
1559
+ message: `Admission '${admission.admissionId}' carries conflicting authoringRevision metadata`
1560
+ };
1561
+ const executionInputRevision = conflictingMetadataNumber(
1562
+ proposal,
1563
+ admission,
1564
+ "executionInputRevision"
1565
+ );
1566
+ if (executionInputRevision !== void 0)
1567
+ return {
1568
+ field: "executionInputRevision",
1569
+ code: "stale-execution-input",
1570
+ ...executionInputRevision,
1571
+ message: `Admission '${admission.admissionId}' carries conflicting executionInputRevision metadata`
1572
+ };
1573
+ const applyPolicyId = conflictingMetadataString(proposal, admission, "applyPolicyId");
1574
+ if (applyPolicyId !== void 0)
1575
+ return {
1576
+ field: "applyPolicyId",
1577
+ code: "policy-mismatch",
1578
+ ...applyPolicyId,
1579
+ message: `Admission '${admission.admissionId}' carries conflicting applyPolicyId metadata`
1580
+ };
1581
+ return void 0;
1582
+ }
1583
+ function conflictingMetadataNumber(proposal, admission, key) {
1584
+ const proposalValue = numberMetadata(proposal.metadata, key);
1585
+ const admissionValue = numberMetadata(admission.metadata, key);
1586
+ if (proposalValue === void 0 || admissionValue === void 0 || proposalValue === admissionValue)
1587
+ return void 0;
1588
+ return { proposalValue, admissionValue };
1589
+ }
1590
+ function conflictingMetadataString(proposal, admission, key) {
1591
+ const proposalValue = stringMetadata(proposal.metadata, key);
1592
+ const admissionValue = stringMetadata(admission.metadata, key);
1593
+ if (proposalValue === void 0 || admissionValue === void 0 || proposalValue === admissionValue)
1594
+ return void 0;
1595
+ return { proposalValue, admissionValue };
1596
+ }
1597
+ function staleRevision(proposal, admission, workItem) {
1598
+ const authoringRevision = numberMetadata(admission.metadata, "authoringRevision") ?? numberMetadata(proposal.metadata, "authoringRevision");
1599
+ if (authoringRevision !== void 0 && authoringRevision !== workItem.authoringRevision)
1600
+ return {
1601
+ kind: "stale-revision",
1602
+ expected: authoringRevision,
1603
+ current: workItem.authoringRevision
1604
+ };
1605
+ const executionInputRevision = numberMetadata(admission.metadata, "executionInputRevision") ?? numberMetadata(proposal.metadata, "executionInputRevision");
1606
+ if (executionInputRevision !== void 0 && executionInputRevision !== workItem.executionInputRevision)
1607
+ return {
1608
+ kind: "stale-execution-input",
1609
+ expected: executionInputRevision,
1610
+ current: workItem.executionInputRevision
1611
+ };
1612
+ return void 0;
1613
+ }
1614
+ function applyPolicyMessage(code, proposal, admission) {
1615
+ if (code === "missing-policy")
1616
+ return `Admitted action '${admission.admissionId}' requires an explicit apply policy`;
1617
+ if (code === "unknown-work-item-domain-action-apply-policy")
1618
+ return `Admitted action '${admission.admissionId}' references a missing apply policy`;
1619
+ return `Admitted action '${proposal.proposalId}' matches multiple apply policies`;
1620
+ }
1621
+ function emitApplication(ctx, state, admission, proposal, applicationState, facts, opts = {}) {
1622
+ const producedFactIds = facts.map((fact) => fact.eventId);
1623
+ const application = {
1624
+ kind: "work-item-domain-action-application",
1625
+ applicationId: `${admission.admissionId}:application`,
1626
+ admissionId: admission.admissionId,
1627
+ proposalId: proposal.proposalId,
1628
+ workItemId: proposal.workItemId,
1629
+ actionKind: proposal.actionKind,
1630
+ state: applicationState,
1631
+ producedFactIds,
1632
+ reason: admission.reason ?? proposal.reason,
1633
+ sourceRefs: admissionRefs(admission, proposal),
1634
+ metadata: { policyId: opts.policyId, code: opts.code }
1635
+ };
1636
+ emitApplicationFact(ctx, "application", application);
1637
+ emitApplicationStatus(ctx, state, {
1638
+ state: applicationState,
1639
+ code: opts.code,
1640
+ message: opts.message,
1641
+ workItemId: proposal.workItemId,
1642
+ proposalId: proposal.proposalId,
1643
+ admissionId: admission.admissionId,
1644
+ actionKind: proposal.actionKind,
1645
+ sourceRefs: application.sourceRefs,
1646
+ metadata: { producedFactIds, policyId: opts.policyId }
1647
+ });
1648
+ }
1649
+ function emitApplicationIssue(ctx, state, key, code, message, workItemId, sourceRefs2, metadata) {
1650
+ if (state.issueKeys.has(key)) return;
1651
+ state.issueKeys.add(key);
1652
+ const item = dataIssue2(code, message, { subjectId: workItemId, refs: sourceRefs2, metadata });
1653
+ emitApplicationFact(ctx, "issue", item);
1654
+ emitApplicationStatus(ctx, state, {
1655
+ state: code === "missing-policy" ? "missing-policy" : "rejected",
1656
+ code,
1657
+ message,
1658
+ workItemId,
1659
+ sourceRefs: sourceRefs2,
1660
+ metadata
1661
+ });
1662
+ }
1663
+ function emitApplicationStatus(ctx, state, status) {
1664
+ state.statusSeq += 1;
1665
+ const statusFact = {
1666
+ kind: "work-item-domain-action-status",
1667
+ statusId: `work-item-domain-action-application-status:${state.statusSeq}`,
1668
+ ...status
1669
+ };
1670
+ emitApplicationFact(ctx, "status", statusFact);
1671
+ emitApplicationAudit(ctx, state, "work-item-domain-action-application-status", statusFact);
1672
+ }
1673
+ function emitApplicationAudit(ctx, state, kind, status) {
1674
+ state.auditSeq += 1;
1675
+ emitApplicationFact(ctx, "audit", auditRecord(kind, state.auditSeq, status));
1676
+ }
1677
+ function emitApplicationFact(ctx, kind, value) {
1678
+ ctx.down([["DATA", { kind, value }]]);
1679
+ }
1680
+ function firstDuplicateFactId(state, facts) {
1681
+ const pending = /* @__PURE__ */ new Set();
1682
+ for (const fact of facts) {
1683
+ if (state.emittedFactIds.has(fact.eventId) || pending.has(fact.eventId)) return fact.eventId;
1684
+ pending.add(fact.eventId);
1685
+ }
1686
+ return void 0;
1687
+ }
1688
+ function claimFactId(state, factId) {
1689
+ if (state.emittedFactIds.has(factId)) return false;
1690
+ state.emittedFactIds.add(factId);
1691
+ return true;
1692
+ }
1693
+ function admissionRefs(admission, proposal, policy) {
1694
+ return uniqueSourceRefs2([
1695
+ ref2("work-item-domain-action-admission", admission.admissionId),
1696
+ ref2("work-item-domain-action-proposal", admission.proposalId),
1697
+ ...proposal === void 0 ? [] : [
1698
+ ref2("work-item", proposal.workItemId),
1699
+ ref2("work-item-evidence", proposal.evidenceId),
1700
+ ...proposal.sourceRefs ?? []
1701
+ ],
1702
+ ...policy === void 0 ? [] : [ref2("work-item-domain-action-apply-policy", policy.policyId)],
1703
+ ...admission.sourceRefs ?? []
1704
+ ]);
1705
+ }
1706
+ function actionSourceRefs(admission, proposal, policy) {
1707
+ return admissionRefs(admission, proposal, policy);
1708
+ }
1709
+
1710
+ // src/solutions/work-item/actions-builders.ts
1711
+ function workItemDomainActionProposal(proposalId, workItemId, actionKind, opts = {}) {
1712
+ return {
1713
+ kind: "work-item-domain-action-proposal",
1714
+ proposalId,
1715
+ workItemId,
1716
+ actionKind,
1717
+ effectRunId: opts.effectRunId ?? `domain-action:${proposalId}:effect-run`,
1718
+ effectRunResultId: opts.effectRunResultId ?? `domain-action:${proposalId}:effect-run-result`,
1719
+ evidenceId: opts.evidenceId ?? `domain-action:${proposalId}:evidence`,
1720
+ policyId: opts.policyId ?? "domain-action-proposal",
1721
+ payload: opts.payload,
1722
+ reason: opts.reason,
1723
+ sourceRefs: opts.sourceRefs,
1724
+ proposedAtMs: opts.proposedAtMs,
1725
+ metadata: opts.metadata
1726
+ };
1727
+ }
1728
+ function workItemDomainActionProposalIntake(proposalId, workItemId, actionKind, opts = {}) {
1729
+ return {
1730
+ kind: "work-item-domain-action-proposal-intake",
1731
+ proposalId,
1732
+ workItemId,
1733
+ actionKind,
1734
+ payload: opts.payload,
1735
+ reason: opts.reason,
1736
+ policyId: opts.policyId,
1737
+ effectRunId: opts.effectRunId,
1738
+ effectRunResultId: opts.effectRunResultId,
1739
+ evidenceId: opts.evidenceId,
1740
+ proposedAtMs: opts.proposedAtMs,
1741
+ sourceRefs: opts.sourceRefs,
1742
+ metadata: opts.metadata
1743
+ };
1744
+ }
1745
+ function workItemDomainActionApplyPolicy(policyId, opts = {}) {
1746
+ return {
1747
+ kind: "work-item-domain-action-apply-policy",
1748
+ policyId,
1749
+ actionKinds: opts.actionKinds,
1750
+ patch: opts.patch,
1751
+ spawn: opts.spawn,
1752
+ metadata: opts.metadata
1753
+ };
1754
+ }
1755
+
1756
+ // src/solutions/work-item/actions-capability-guard.ts
1757
+ function workItemDomainActionCapabilityGuardProjector(graph, opts) {
1758
+ const name = opts.name ?? "workItemDomainActionCapabilityGuard";
1759
+ const deps = opts.capabilityAdmissionStatus === void 0 ? [opts.proposals, opts.capabilityAdmissions, opts.guardPolicies] : [
1760
+ opts.proposals,
1761
+ opts.capabilityAdmissions,
1762
+ opts.guardPolicies,
1763
+ opts.capabilityAdmissionStatus
1764
+ ];
1765
+ const statusIndex = opts.capabilityAdmissionStatus === void 0 ? -1 : 3;
1766
+ const now = opts.now ?? Date.now;
1767
+ const runtime = graph.node(
1768
+ deps,
1769
+ (ctx) => {
1770
+ const state = ctx.state.get() ?? {
1771
+ proposals: /* @__PURE__ */ new Map(),
1772
+ admissionsByCapability: /* @__PURE__ */ new Map(),
1773
+ issueStatusesByCapability: /* @__PURE__ */ new Map(),
1774
+ issueStatusesWithoutCapability: [],
1775
+ policies: /* @__PURE__ */ new Map(),
1776
+ emittedProposalDecisions: /* @__PURE__ */ new Set(),
1777
+ emittedStatusKeys: /* @__PURE__ */ new Set(),
1778
+ issueKeys: /* @__PURE__ */ new Set(),
1779
+ statusSeq: 0,
1780
+ auditSeq: 0
1781
+ };
1782
+ for (const raw of depBatch(ctx, 2) ?? []) {
1783
+ const policyIssue = capabilityGuardPolicyIssue(raw);
1784
+ if (policyIssue !== void 0) {
1785
+ emitCapabilityGuardIssue(
1786
+ ctx,
1787
+ state,
1788
+ `malformed-policy:${recordString(raw, "policyId") ?? "unknown"}`,
1789
+ policyIssue
1790
+ );
1791
+ continue;
1792
+ }
1793
+ const policy = raw;
1794
+ state.policies.set(policy.policyId, policy);
1795
+ }
1796
+ for (const raw of depBatch(ctx, 1) ?? []) {
1797
+ const admissionIssue = capabilityAdmissionIssue(raw);
1798
+ if (admissionIssue !== void 0) {
1799
+ emitCapabilityGuardIssue(
1800
+ ctx,
1801
+ state,
1802
+ `malformed-admission:${recordString(raw, "admissionId") ?? "unknown"}`,
1803
+ admissionIssue
1804
+ );
1805
+ continue;
1806
+ }
1807
+ const admission = raw;
1808
+ const capabilityKey = capabilityBoundaryRefId(admission.capability);
1809
+ const byCapability = state.admissionsByCapability.get(capabilityKey) ?? [];
1810
+ if (!byCapability.some((item) => item.admissionId === admission.admissionId)) {
1811
+ state.admissionsByCapability.set(capabilityKey, [...byCapability, admission]);
1812
+ }
1813
+ }
1814
+ if (statusIndex >= 0) {
1815
+ for (const raw of depBatch(ctx, statusIndex) ?? []) {
1816
+ const statusIssue = capabilityAdmissionStatusIssue(raw);
1817
+ if (statusIssue !== void 0) {
1818
+ emitCapabilityGuardIssue(
1819
+ ctx,
1820
+ state,
1821
+ `malformed-capability-status:${recordString(raw, "statusId") ?? "unknown"}`,
1822
+ statusIssue
1823
+ );
1824
+ continue;
1825
+ }
1826
+ const status = raw;
1827
+ if (status.state !== "capability-admission-issue") continue;
1828
+ const capabilityId = status.capabilityId;
1829
+ const capabilityKind = status.capabilityKind;
1830
+ if (capabilityId !== void 0 && capabilityKind !== void 0) {
1831
+ const capabilityKey = capabilityBoundaryRefId({
1832
+ id: capabilityId,
1833
+ kind: capabilityKind
1834
+ });
1835
+ const statuses = state.issueStatusesByCapability.get(capabilityKey) ?? [];
1836
+ if (!statuses.some((item) => item.statusId === status.statusId)) {
1837
+ state.issueStatusesByCapability.set(capabilityKey, [...statuses, status]);
1838
+ }
1839
+ } else if (!state.issueStatusesWithoutCapability.some((item) => item.statusId === status.statusId)) {
1840
+ state.issueStatusesWithoutCapability.push(status);
1841
+ }
1842
+ for (const proposal of state.proposals.values())
1843
+ emitCapabilityStatusIssueForProposal(ctx, state, proposal, status);
1844
+ }
1845
+ }
1846
+ for (const raw of depBatch(ctx, 0) ?? []) {
1847
+ const proposalIssue = capabilityGuardProposalIssue(raw);
1848
+ if (proposalIssue !== void 0) {
1849
+ emitCapabilityGuardIssue(
1850
+ ctx,
1851
+ state,
1852
+ `malformed-proposal:${recordString(raw, "proposalId") ?? "unknown"}`,
1853
+ proposalIssue
1854
+ );
1855
+ continue;
1856
+ }
1857
+ const proposal = raw;
1858
+ state.proposals.set(proposal.proposalId, proposal);
1859
+ }
1860
+ for (const proposal of state.proposals.values())
1861
+ evaluateCapabilityGuardProposal(ctx, state, proposal, now());
1862
+ ctx.state.set(state);
1863
+ },
1864
+ {
1865
+ name: `${name}/runtime`,
1866
+ factory: "workItemDomainActionCapabilityGuardProjector",
1867
+ partial: true,
1868
+ completeWhenDepsComplete: false,
1869
+ errorWhenDepsError: false
1870
+ }
1871
+ );
1872
+ return {
1873
+ decisions: project(
1874
+ graph,
1875
+ runtime,
1876
+ `${name}/decisions`,
1877
+ "workItemDomainActionCapabilityGuardDecisions",
1878
+ (fact) => fact.kind === "decision" ? fact.value : void 0
1879
+ ),
1880
+ status: project(
1881
+ graph,
1882
+ runtime,
1883
+ `${name}/status`,
1884
+ "workItemDomainActionCapabilityGuardStatus",
1885
+ (fact) => fact.kind === "status" ? fact.value : void 0
1886
+ ),
1887
+ issues: project(
1888
+ graph,
1889
+ runtime,
1890
+ `${name}/issues`,
1891
+ "workItemDomainActionCapabilityGuardIssues",
1892
+ (fact) => fact.kind === "issue" ? fact.value : void 0
1893
+ ),
1894
+ audit: project(
1895
+ graph,
1896
+ runtime,
1897
+ `${name}/audit`,
1898
+ "workItemDomainActionCapabilityGuardAudit",
1899
+ (fact) => fact.kind === "audit" ? fact.value : void 0
1900
+ )
1901
+ };
1902
+ }
1903
+ function evaluateCapabilityGuardProposal(ctx, state, proposal, decidedAtMs) {
1904
+ if (state.emittedProposalDecisions.has(proposal.proposalId)) return;
1905
+ const policy = selectCapabilityGuardPolicy(state, proposal);
1906
+ if (typeof policy === "string") {
1907
+ emitCapabilityGuardIssue(
1908
+ ctx,
1909
+ state,
1910
+ `policy:${proposal.proposalId}:${policy}`,
1911
+ dataIssue2(policy, capabilityGuardPolicyMessage(policy, proposal), {
1912
+ subjectId: proposal.workItemId,
1913
+ refs: [ref2("work-item-domain-action-proposal", proposal.proposalId)]
1914
+ })
1915
+ );
1916
+ return;
1917
+ }
1918
+ for (const status of state.issueStatusesWithoutCapability)
1919
+ emitCapabilityStatusIssueForProposal(ctx, state, proposal, status);
1920
+ for (const capabilityRef of policy.capabilityRefs) {
1921
+ for (const status of state.issueStatusesByCapability.get(
1922
+ capabilityBoundaryRefId(capabilityRef)
1923
+ ) ?? [])
1924
+ emitCapabilityStatusIssueForProposal(ctx, state, proposal, status);
1925
+ }
1926
+ const admissions = policy.capabilityRefs.map(
1927
+ (capabilityRef) => latestCapabilityAdmission(state, policy, capabilityRef)
1928
+ );
1929
+ const missingCapabilityRefs = policy.capabilityRefs.filter(
1930
+ (_, index) => admissions[index] === void 0
1931
+ );
1932
+ const deferredCapabilityRefs = admissions.filter((admission) => admission !== void 0).filter((admission) => admission.state === "deferred").map((admission) => capabilityBoundaryRefId(admission.capability));
1933
+ if (missingCapabilityRefs.length > 0 || deferredCapabilityRefs.length > 0) {
1934
+ emitCapabilityGuardStatusOnce(
1935
+ ctx,
1936
+ state,
1937
+ `deferred:${proposal.proposalId}:${policy.policyId}:missing=${missingCapabilityRefs.map(capabilityBoundaryRefId).join(",")}:deferred=${deferredCapabilityRefs.join(",")}`,
1938
+ {
1939
+ state: "deferred",
1940
+ workItemId: proposal.workItemId,
1941
+ proposalId: proposal.proposalId,
1942
+ actionKind: proposal.actionKind,
1943
+ policyId: policy.policyId,
1944
+ capabilityRefs: policy.capabilityRefs,
1945
+ admissionSubjectIds: policy.admissionSubjectIds,
1946
+ message: "WorkItem domain action is waiting for capability admission",
1947
+ sourceRefs: capabilityGuardRefs(proposal, policy, admissions),
1948
+ metadata: {
1949
+ missingCapabilityRefs: missingCapabilityRefs.map(capabilityBoundaryRefId),
1950
+ deferredCapabilityRefs
1951
+ }
1952
+ }
1953
+ );
1954
+ return;
1955
+ }
1956
+ const presentAdmissions = admissions.filter(
1957
+ (admission) => admission !== void 0
1958
+ );
1959
+ const blocked = presentAdmissions.filter((admission) => admission.state === "blocked");
1960
+ const outcome = blocked.length === 0 ? "admit" : "reject";
1961
+ const decision = {
1962
+ kind: "work-item-domain-action-admission-decision",
1963
+ decisionId: `capability-guard:${proposal.proposalId}:decision`,
1964
+ admissionId: `capability-guard:${proposal.proposalId}:admission`,
1965
+ proposalId: proposal.proposalId,
1966
+ outcome,
1967
+ reason: blocked.length === 0 ? "Capability guard admitted required capabilities" : "Capability guard rejected blocked capabilities",
1968
+ decidedAtMs,
1969
+ sourceRefs: capabilityGuardRefs(proposal, policy, presentAdmissions),
1970
+ metadata: {
1971
+ capabilityGuardPolicyId: policy.policyId,
1972
+ capabilityRefs: policy.capabilityRefs.map(capabilityBoundaryRefId),
1973
+ admissionSubjectIds: policy.admissionSubjectIds,
1974
+ blockedCapabilityRefs: blocked.map(
1975
+ (admission) => capabilityBoundaryRefId(admission.capability)
1976
+ )
1977
+ }
1978
+ };
1979
+ state.emittedProposalDecisions.add(proposal.proposalId);
1980
+ emitCapabilityGuard(ctx, "decision", decision);
1981
+ emitCapabilityGuardStatus(ctx, state, {
1982
+ state: outcome === "admit" ? "admitted" : "rejected",
1983
+ workItemId: proposal.workItemId,
1984
+ proposalId: proposal.proposalId,
1985
+ actionKind: proposal.actionKind,
1986
+ policyId: policy.policyId,
1987
+ capabilityRefs: policy.capabilityRefs,
1988
+ admissionSubjectIds: policy.admissionSubjectIds,
1989
+ admissionIds: presentAdmissions.map((admission) => admission.admissionId),
1990
+ sourceRefs: decision.sourceRefs,
1991
+ metadata: { decisionId: decision.decisionId, admissionId: decision.admissionId }
1992
+ });
1993
+ }
1994
+ function capabilityGuardProposalIssue(proposal) {
1995
+ if (!isRecord(proposal) || proposal.kind !== "work-item-domain-action-proposal" || typeof proposal.proposalId !== "string" || proposal.proposalId.length === 0 || typeof proposal.workItemId !== "string" || proposal.workItemId.length === 0 || typeof proposal.actionKind !== "string" || proposal.actionKind.length === 0 || proposal.sourceRefs !== void 0 && !isSourceRefArray(proposal.sourceRefs)) {
1996
+ return dataIssue2(
1997
+ "malformed-work-item-domain-action-capability-guard-proposal",
1998
+ "WorkItem domain action capability guard requires valid proposal DATA facts",
1999
+ { subjectId: recordString(proposal, "workItemId") }
2000
+ );
2001
+ }
2002
+ return void 0;
2003
+ }
2004
+ function capabilityGuardPolicyIssue(policy) {
2005
+ if (!isRecord(policy) || policy.kind !== "work-item-domain-action-capability-guard-policy" || typeof policy.policyId !== "string" || policy.policyId.length === 0 || !Array.isArray(policy.capabilityRefs) || policy.capabilityRefs.length === 0 || !policy.capabilityRefs.every(isBoundaryCapabilityRef) || !Array.isArray(policy.admissionSubjectIds) || policy.admissionSubjectIds.length === 0 || !policy.admissionSubjectIds.every((id) => typeof id === "string" && id.length > 0) || policy.actionKinds !== void 0 && (!Array.isArray(policy.actionKinds) || !policy.actionKinds.every((kind) => typeof kind === "string" && kind.length > 0))) {
2006
+ return dataIssue2(
2007
+ "malformed-work-item-domain-action-capability-guard-policy",
2008
+ "WorkItem domain action capability guard policy requires policyId, capabilityRefs, and admissionSubjectIds",
2009
+ {
2010
+ subjectId: recordString(policy, "policyId")
2011
+ }
2012
+ );
2013
+ }
2014
+ return void 0;
2015
+ }
2016
+ function capabilityAdmissionIssue(admission) {
2017
+ if (!isRecord(admission) || admission.kind !== "capability-admission" || typeof admission.admissionId !== "string" || admission.admissionId.length === 0 || typeof admission.proposalId !== "string" || admission.proposalId.length === 0 || typeof admission.subjectId !== "string" || admission.subjectId.length === 0 || !isBoundaryCapabilityRef(admission.capability) || !isCapabilityAdmissionState(admission.state) || typeof admission.decisionId !== "string" || admission.decisionId.length === 0 || admission.sourceRefs !== void 0 && !isSourceRefArray(admission.sourceRefs)) {
2018
+ return dataIssue2(
2019
+ "malformed-capability-admission",
2020
+ "WorkItem domain action capability guard requires valid CapabilityAdmission DATA facts",
2021
+ { subjectId: recordString(admission, "subjectId") }
2022
+ );
2023
+ }
2024
+ return void 0;
2025
+ }
2026
+ function capabilityAdmissionStatusIssue(status) {
2027
+ if (!isRecord(status) || status.kind !== "capability-admission-status" || typeof status.statusId !== "string" || status.statusId.length === 0 || !isCapabilityAdmissionStatusState(status.state)) {
2028
+ return dataIssue2(
2029
+ "malformed-capability-admission-status",
2030
+ "WorkItem domain action capability guard requires valid CapabilityAdmissionStatus DATA facts",
2031
+ { subjectId: recordString(status, "subjectId") }
2032
+ );
2033
+ }
2034
+ const hasCapabilityId = status.capabilityId !== void 0;
2035
+ const hasCapabilityKind = status.capabilityKind !== void 0;
2036
+ if (hasCapabilityId !== hasCapabilityKind || hasCapabilityId && (typeof status.capabilityId !== "string" || status.capabilityId.length === 0 || !isBoundaryCapabilityKind(status.capabilityKind)) || status.sourceRefs !== void 0 && !isSourceRefArray(status.sourceRefs) || status.issues !== void 0 && !isDataIssueArray(status.issues)) {
2037
+ return dataIssue2(
2038
+ "malformed-capability-admission-status",
2039
+ "WorkItem domain action capability guard requires valid CapabilityAdmissionStatus DATA facts",
2040
+ { subjectId: recordString(status, "subjectId") }
2041
+ );
2042
+ }
2043
+ return void 0;
2044
+ }
2045
+ function isCapabilityAdmissionState(value) {
2046
+ return value === "allowed" || value === "blocked" || value === "deferred";
2047
+ }
2048
+ function isCapabilityAdmissionStatusState(value) {
2049
+ return value === "capability-admission-allowed" || value === "capability-admission-blocked" || value === "capability-admission-deferred" || value === "capability-admission-issue";
2050
+ }
2051
+ function isSourceRefArray(value) {
2052
+ return Array.isArray(value) && value.every(
2053
+ (item) => isRecord(item) && typeof item.kind === "string" && typeof item.id === "string"
2054
+ );
2055
+ }
2056
+ function isDataIssueArray(value) {
2057
+ return Array.isArray(value) && value.every(isDataIssue);
2058
+ }
2059
+ function isDataIssue(value) {
2060
+ return isRecord(value) && value.kind === "issue" && typeof value.code === "string" && value.code.length > 0 && typeof value.message === "string" && value.message.length > 0;
2061
+ }
2062
+ function isBoundaryCapabilityRef(value) {
2063
+ return isRecord(value) && typeof value.id === "string" && value.id.length > 0 && isBoundaryCapabilityKind(value.kind) && typeof value.required === "boolean" && (value.sourceRefs === void 0 || Array.isArray(value.sourceRefs) && value.sourceRefs.every((sourceRef) => typeof sourceRef === "string"));
2064
+ }
2065
+ function isBoundaryCapabilityKind(value) {
2066
+ return value === "auth" || value === "permission" || value === "config" || value === "resource";
2067
+ }
2068
+ function selectCapabilityGuardPolicy(state, proposal) {
2069
+ const explicitId = stringMetadata(proposal.metadata, "capabilityGuardPolicyId") ?? proposal.sourceRefs?.find(
2070
+ (sourceRef) => sourceRef.kind === "work-item-domain-action-capability-guard-policy"
2071
+ )?.id;
2072
+ if (explicitId !== void 0)
2073
+ return state.policies.get(explicitId) ?? "unknown-work-item-domain-action-capability-guard-policy";
2074
+ const matching = [...state.policies.values()].filter(
2075
+ (policy) => policy.actionKinds === void 0 || policy.actionKinds.includes(proposal.actionKind)
2076
+ );
2077
+ if (matching.length === 0) return "missing-policy";
2078
+ if (matching.length > 1) return "policy-mismatch";
2079
+ return matching[0];
2080
+ }
2081
+ function latestCapabilityAdmission(state, policy, capabilityRef) {
2082
+ const admissions = state.admissionsByCapability.get(capabilityBoundaryRefId(capabilityRef)) ?? [];
2083
+ for (let index = admissions.length - 1; index >= 0; index -= 1) {
2084
+ const admission = admissions[index];
2085
+ if (admission !== void 0 && policy.admissionSubjectIds.includes(admission.subjectId))
2086
+ return admission;
2087
+ }
2088
+ return void 0;
2089
+ }
2090
+ function emitCapabilityStatusIssueForProposal(ctx, state, proposal, status) {
2091
+ const policy = selectCapabilityGuardPolicy(state, proposal);
2092
+ if (typeof policy === "string") return;
2093
+ if (status.subjectId !== void 0 && !policy.admissionSubjectIds.includes(status.subjectId))
2094
+ return;
2095
+ const capabilityId = status.capabilityId;
2096
+ const capabilityKind = status.capabilityKind;
2097
+ const statusCapabilityKey = capabilityId === void 0 || capabilityKind === void 0 ? void 0 : capabilityBoundaryRefId({ id: capabilityId, kind: capabilityKind });
2098
+ if (statusCapabilityKey !== void 0 && !policy.capabilityRefs.some(
2099
+ (capabilityRef) => capabilityBoundaryRefId(capabilityRef) === statusCapabilityKey
2100
+ ))
2101
+ return;
2102
+ const issue2 = status.issues?.[0] ?? dataIssue2(
2103
+ "capability-admission-status-issue",
2104
+ "Capability admission status reported an issue",
2105
+ { subjectId: proposal.workItemId }
2106
+ );
2107
+ emitCapabilityGuardIssue(
2108
+ ctx,
2109
+ state,
2110
+ `capability-status:${proposal.proposalId}:${status.statusId}`,
2111
+ dataIssue2(issue2.code, issue2.message, {
2112
+ subjectId: proposal.workItemId,
2113
+ refs: uniqueSourceRefs2([
2114
+ ...capabilityGuardRefs(proposal, policy),
2115
+ ...status.sourceRefs ?? []
2116
+ ]),
2117
+ metadata: {
2118
+ ...statusCapabilityKey === void 0 ? {} : { capabilityRef: statusCapabilityKey },
2119
+ capabilityAdmissionStatusId: status.statusId
2120
+ }
2121
+ })
2122
+ );
2123
+ }
2124
+ function capabilityGuardPolicyMessage(code, proposal) {
2125
+ if (code === "missing-policy")
2126
+ return `WorkItem domain action '${proposal.proposalId}' has no capability guard policy`;
2127
+ if (code === "unknown-work-item-domain-action-capability-guard-policy")
2128
+ return `WorkItem domain action '${proposal.proposalId}' references a missing capability guard policy`;
2129
+ return `WorkItem domain action '${proposal.proposalId}' matches multiple capability guard policies`;
2130
+ }
2131
+ function capabilityGuardRefs(proposal, policy, admissions = []) {
2132
+ return uniqueSourceRefs2([
2133
+ ref2("work-item", proposal.workItemId),
2134
+ ref2("work-item-domain-action-proposal", proposal.proposalId),
2135
+ ref2("work-item-domain-action-capability-guard-policy", policy.policyId),
2136
+ ...admissions.filter((admission) => admission !== void 0).flatMap((admission) => [
2137
+ ref2("capability-admission", admission.admissionId),
2138
+ ref2("capability-admission-proposal", admission.proposalId),
2139
+ ref2("boundary-capability", capabilityBoundaryRefId(admission.capability)),
2140
+ ...admission.sourceRefs ?? []
2141
+ ]),
2142
+ ...proposal.sourceRefs ?? []
2143
+ ]);
2144
+ }
2145
+ function capabilityBoundaryRefId(capability) {
2146
+ return `${capability.kind}:${capability.id}`;
2147
+ }
2148
+ function emitCapabilityGuardStatus(ctx, state, status) {
2149
+ state.statusSeq += 1;
2150
+ const statusFact = {
2151
+ kind: "work-item-domain-action-capability-guard-status",
2152
+ statusId: `work-item-domain-action-capability-guard-status:${state.statusSeq}`,
2153
+ ...status
2154
+ };
2155
+ emitCapabilityGuard(ctx, "status", statusFact);
2156
+ state.auditSeq += 1;
2157
+ emitCapabilityGuard(ctx, "audit", {
2158
+ id: `work-item-domain-action-capability-guard-status:${state.auditSeq}`,
2159
+ kind: "work-item-domain-action-capability-guard-status",
2160
+ subjectId: status.workItemId,
2161
+ message: status.message,
2162
+ sourceRefs: status.sourceRefs,
2163
+ metadata: {
2164
+ statusId: statusFact.statusId,
2165
+ state: status.state,
2166
+ proposalId: status.proposalId,
2167
+ policyId: status.policyId,
2168
+ ...status.metadata ?? {}
2169
+ }
2170
+ });
2171
+ }
2172
+ function emitCapabilityGuardStatusOnce(ctx, state, key, status) {
2173
+ if (state.emittedStatusKeys.has(key)) return;
2174
+ state.emittedStatusKeys.add(key);
2175
+ emitCapabilityGuardStatus(ctx, state, status);
2176
+ }
2177
+ function emitCapabilityGuardIssue(ctx, state, key, issue2) {
2178
+ if (state.issueKeys.has(key)) return;
2179
+ state.issueKeys.add(key);
2180
+ emitCapabilityGuard(ctx, "issue", issue2);
2181
+ emitCapabilityGuardStatus(ctx, state, {
2182
+ state: "issue",
2183
+ workItemId: issue2.subjectId,
2184
+ issues: [issue2],
2185
+ message: issue2.message,
2186
+ metadata: { issueCode: issue2.code }
2187
+ });
2188
+ }
2189
+ function emitCapabilityGuard(ctx, kind, value) {
2190
+ ctx.down([["DATA", { kind, value }]]);
2191
+ }
2192
+
2193
+ // src/solutions/work-item/actions-intake.ts
2194
+ function workItemDomainActionProposalIntakeProjector(graph, opts) {
2195
+ const name = opts.name ?? "workItemDomainActionIntake";
2196
+ const now = opts.now ?? Date.now;
2197
+ const runtime = graph.node(
2198
+ [opts.proposals],
2199
+ (ctx) => {
2200
+ const state = ctx.state.get() ?? {
2201
+ proposals: /* @__PURE__ */ new Set(),
2202
+ statusSeq: 0,
2203
+ auditSeq: 0
2204
+ };
2205
+ for (const raw of depBatch(ctx, 0) ?? []) reduceProposalIntake(ctx, state, raw, now());
2206
+ ctx.state.set(state);
2207
+ },
2208
+ {
2209
+ name: `${name}/runtime`,
2210
+ factory: "workItemDomainActionProposalIntakeProjector",
2211
+ partial: true,
2212
+ completeWhenDepsComplete: false,
2213
+ errorWhenDepsError: false
2214
+ }
2215
+ );
2216
+ return {
2217
+ proposals: project(
2218
+ graph,
2219
+ runtime,
2220
+ `${name}/proposals`,
2221
+ "workItemDomainActionProposals",
2222
+ (fact) => fact.kind === "proposal" ? fact.value : void 0
2223
+ ),
2224
+ status: project(
2225
+ graph,
2226
+ runtime,
2227
+ `${name}/status`,
2228
+ "workItemDomainActionStatus",
2229
+ (fact) => fact.kind === "status" ? fact.value : void 0
2230
+ ),
2231
+ issues: project(
2232
+ graph,
2233
+ runtime,
2234
+ `${name}/issues`,
2235
+ "workItemDomainActionIssues",
2236
+ (fact) => fact.kind === "issue" ? fact.value : void 0
2237
+ ),
2238
+ audit: project(
2239
+ graph,
2240
+ runtime,
2241
+ `${name}/audit`,
2242
+ "workItemDomainActionAudit",
2243
+ (fact) => fact.kind === "audit" ? fact.value : void 0
2244
+ )
2245
+ };
2246
+ }
2247
+ function reduceProposalIntake(ctx, state, input, proposedAtMs) {
2248
+ const proposal = normalizeProposal(input, proposedAtMs);
2249
+ if (typeof proposal === "string") {
2250
+ const issue2 = dataIssue2("malformed-domain-action-proposal", proposal);
2251
+ emitIntake(ctx, "issue", issue2);
2252
+ emitIntakeStatus(ctx, state, {
2253
+ state: "rejected",
2254
+ code: issue2.code,
2255
+ message: issue2.message
2256
+ });
2257
+ return;
2258
+ }
2259
+ if (state.proposals.has(proposal.proposalId)) {
2260
+ emitIntakeStatus(ctx, state, {
2261
+ state: "duplicate",
2262
+ code: "duplicate-suppressed",
2263
+ workItemId: proposal.workItemId,
2264
+ proposalId: proposal.proposalId,
2265
+ actionKind: proposal.actionKind,
2266
+ message: `Duplicate WorkItem domain action proposal '${proposal.proposalId}' suppressed`
2267
+ });
2268
+ return;
2269
+ }
2270
+ state.proposals.add(proposal.proposalId);
2271
+ emitIntake(ctx, "proposal", proposal);
2272
+ emitIntakeStatus(ctx, state, {
2273
+ state: "proposed",
2274
+ workItemId: proposal.workItemId,
2275
+ proposalId: proposal.proposalId,
2276
+ actionKind: proposal.actionKind,
2277
+ sourceRefs: proposal.sourceRefs
2278
+ });
2279
+ }
2280
+ function normalizeProposal(input, proposedAtMs) {
2281
+ if (!isRecord(input)) return "WorkItemDomainActionProposal intake must be an object";
2282
+ if (input.kind !== "work-item-domain-action-proposal" && input.kind !== "work-item-domain-action-proposal-intake")
2283
+ return "WorkItemDomainActionProposal intake has unsupported kind";
2284
+ if (typeof input.proposalId !== "string" || input.proposalId.trim() === "")
2285
+ return "WorkItemDomainActionProposal.proposalId is required";
2286
+ if (typeof input.workItemId !== "string" || input.workItemId.trim() === "")
2287
+ return "WorkItemDomainActionProposal.workItemId is required";
2288
+ if (typeof input.actionKind !== "string" || input.actionKind.trim() === "")
2289
+ return "WorkItemDomainActionProposal.actionKind is required";
2290
+ if (input.kind === "work-item-domain-action-proposal") {
2291
+ if (typeof input.effectRunId !== "string")
2292
+ return "WorkItemDomainActionProposal.effectRunId is required";
2293
+ if (typeof input.effectRunResultId !== "string")
2294
+ return "WorkItemDomainActionProposal.effectRunResultId is required";
2295
+ if (typeof input.evidenceId !== "string")
2296
+ return "WorkItemDomainActionProposal.evidenceId is required";
2297
+ if (typeof input.policyId !== "string")
2298
+ return "WorkItemDomainActionProposal.policyId is required";
2299
+ return input;
2300
+ }
2301
+ return workItemDomainActionProposal(
2302
+ input.proposalId,
2303
+ input.workItemId,
2304
+ input.actionKind,
2305
+ {
2306
+ payload: input.payload,
2307
+ reason: typeof input.reason === "string" ? input.reason : void 0,
2308
+ policyId: typeof input.policyId === "string" ? input.policyId : void 0,
2309
+ effectRunId: typeof input.effectRunId === "string" ? input.effectRunId : void 0,
2310
+ effectRunResultId: typeof input.effectRunResultId === "string" ? input.effectRunResultId : void 0,
2311
+ evidenceId: typeof input.evidenceId === "string" ? input.evidenceId : void 0,
2312
+ proposedAtMs: typeof input.proposedAtMs === "number" ? input.proposedAtMs : proposedAtMs,
2313
+ sourceRefs: sourceRefs(input.sourceRefs),
2314
+ metadata: isRecord(input.metadata) ? input.metadata : void 0
2315
+ }
2316
+ );
2317
+ }
2318
+ function emitIntakeStatus(ctx, state, status) {
2319
+ state.statusSeq += 1;
2320
+ const statusFact = {
2321
+ kind: "work-item-domain-action-status",
2322
+ statusId: `work-item-domain-action-intake-status:${state.statusSeq}`,
2323
+ ...status
2324
+ };
2325
+ emitIntake(ctx, "status", statusFact);
2326
+ emitIntakeAudit(ctx, state, "work-item-domain-action-intake-status", statusFact);
2327
+ }
2328
+ function emitIntakeAudit(ctx, state, kind, status) {
2329
+ state.auditSeq += 1;
2330
+ emitIntake(ctx, "audit", auditRecord(kind, state.auditSeq, status));
2331
+ }
2332
+ function emitIntake(ctx, kind, value) {
2333
+ ctx.down([["DATA", { kind, value }]]);
2334
+ }
2335
+ // Annotate the CommonJS export names for ESM import in node:
2336
+ 0 && (module.exports = {
2337
+ workItemDomainActionAdmissionProjector,
2338
+ workItemDomainActionApplicationProjector,
2339
+ workItemDomainActionApplyPolicy,
2340
+ workItemDomainActionCapabilityGuardProjector,
2341
+ workItemDomainActionProposal,
2342
+ workItemDomainActionProposalIntake,
2343
+ workItemDomainActionProposalIntakeProjector
2344
+ });
2345
+ //# sourceMappingURL=actions.cjs.map