@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
@@ -1,520 +1,530 @@
1
1
  import {
2
2
  memoryRetrievalBundle,
3
3
  validateMemoryFragment
4
- } from "./chunk-JIMUDQN3.js";
5
- import {
6
- strictJsonCodec
7
- } from "./chunk-4VLAQHZI.js";
4
+ } from "./chunk-E4QCH32M.js";
8
5
  import {
9
6
  depBatch,
10
7
  depLatest
11
- } from "./chunk-SWTLEQL6.js";
8
+ } from "./chunk-WQIA3GFB.js";
9
+ import {
10
+ strictJsonCodec
11
+ } from "./chunk-K7FB3JTD.js";
12
12
 
13
- // src/solutions/agentic-memory.ts
14
- var AGENTIC_MEMORY_RECORD_FRAME_FORMAT = "graphrefly.agenticMemoryRecord";
15
- var AGENTIC_MEMORY_RECORD_FRAME_VERSION = 1;
16
- function agenticMemoryBundle(graph, opts) {
17
- const name = opts.name ?? "agenticMemory";
18
- const projection = agenticMemoryRecordProjection(graph, opts.records, `${name}/projection`);
19
- const projectedRecords = agenticMemoryProjection(
20
- graph,
21
- projection,
22
- `${name}/records`,
23
- "agenticMemoryRecords",
24
- (fact) => fact.records
25
- );
26
- const projectedFragments = agenticMemoryProjection(
27
- graph,
28
- projection,
29
- `${name}/fragments`,
30
- "agenticMemoryFragments",
31
- (fact) => fact.fragments
32
- );
33
- const status = agenticMemoryProjection(
34
- graph,
35
- projection,
36
- `${name}/status`,
37
- "agenticMemoryStatus",
38
- (fact) => fact.status
39
- );
40
- const errors = agenticMemoryProjection(
41
- graph,
42
- projection,
43
- `${name}/errors`,
44
- "agenticMemoryErrors",
45
- (fact) => fact.errors
46
- );
47
- const retrieval = memoryRetrievalBundle(graph, {
48
- name: `${name}/retrieval`,
49
- fragments: projectedFragments,
50
- query: opts.query
51
- });
52
- const sources = agenticMemoryProjection(
53
- graph,
54
- projection,
55
- `${name}/sources`,
56
- "agenticMemorySources",
57
- (fact) => Object.freeze(
58
- fact.fragments.map(
59
- (fragment) => Object.freeze({
60
- fragmentId: fragment.id,
61
- ...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
62
- sources: Object.freeze([...fragment.sources]),
63
- ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
64
- ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
65
- })
66
- )
67
- )
68
- );
69
- const context = agenticMemoryContextProjection(
70
- graph,
71
- projection,
72
- retrieval.snapshot,
73
- `${name}/context`
74
- );
75
- return {
76
- input: { records: opts.records, query: opts.query },
77
- projection,
78
- retrieval,
79
- retrievalSnapshot: retrieval.snapshot,
80
- records: projectedRecords,
81
- fragments: projectedFragments,
82
- sources,
83
- indexed: retrieval.indexed,
84
- ranked: retrieval.ranked,
85
- context,
86
- status,
87
- errors,
88
- retrievalStatus: retrieval.status,
89
- retrievalErrors: retrieval.errors,
90
- cursor: retrieval.cursor
91
- };
92
- }
93
- function agenticMemoryKgProjectionBundle(graph, opts) {
94
- const name = opts.name ?? "agenticMemoryKgProjection";
95
- const projection = graph.node(
96
- [opts.records, opts.drafts],
97
- (ctx) => {
98
- const state = ctx.state.get() ?? { evaluation: 0 };
99
- state.evaluation += 1;
100
- const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
101
- const draftProjection = validateAndProjectKgDrafts(
102
- depLatest(ctx, 1),
103
- recordProjection.records
104
- );
105
- const cursor = Object.freeze({
106
- evaluation: state.evaluation,
107
- validRecords: recordProjection.records.length,
108
- validDrafts: draftProjection.assertions.length,
109
- invalidDrafts: draftProjection.invalidDrafts,
110
- projectedAssertions: draftProjection.assertions.length
13
+ // src/solutions/agentic-memory-shared.ts
14
+ function validateAndProjectRecords(value) {
15
+ const records = [];
16
+ const fragments = [];
17
+ const metadataByFragmentId = /* @__PURE__ */ Object.create(null);
18
+ const errors = [];
19
+ const invalidRecordIndexes = /* @__PURE__ */ new Set();
20
+ const seenRecordIds = /* @__PURE__ */ new Set();
21
+ const seenFragmentIds = /* @__PURE__ */ new Set();
22
+ if (!Array.isArray(value)) {
23
+ errors.push({
24
+ code: "invalid-records-input",
25
+ message: "agenticMemoryBundle: records input must be an array",
26
+ record: value
27
+ });
28
+ return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
29
+ }
30
+ const length = safeArrayLength(value);
31
+ if (length === void 0) {
32
+ errors.push({
33
+ code: "invalid-records-input",
34
+ message: "agenticMemoryBundle: records input length could not be read",
35
+ record: value
36
+ });
37
+ return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
38
+ }
39
+ for (let i = 0; i < length; i += 1) {
40
+ let raw;
41
+ try {
42
+ raw = value[i];
43
+ } catch (error) {
44
+ invalidRecordIndexes.add(i);
45
+ errors.push({
46
+ code: "invalid-record",
47
+ message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
48
+ index: i,
49
+ validationErrors: Object.freeze(["record access failed"])
111
50
  });
112
- const errors = Object.freeze(
113
- [...recordProjection.errors.map(kgErrorFromRecordError), ...draftProjection.errors].map(
114
- (error) => freezeError({ ...error, cursor })
115
- )
116
- );
117
- const status = Object.freeze({
118
- state: agenticStatusState(errors.length, draftProjection.assertions.length),
119
- cursor
51
+ continue;
52
+ }
53
+ const result = validateAndSnapshotRecord(raw, i);
54
+ if (result.errors.length > 0) {
55
+ invalidRecordIndexes.add(i);
56
+ errors.push(...result.errors);
57
+ continue;
58
+ }
59
+ if (result.record === void 0) continue;
60
+ if (seenRecordIds.has(result.record.id)) {
61
+ invalidRecordIndexes.add(i);
62
+ errors.push({
63
+ code: "duplicate-record-id",
64
+ message: "agenticMemoryBundle: duplicate record id",
65
+ index: i,
66
+ recordId: result.record.id,
67
+ record: raw,
68
+ validationErrors: [`duplicate record id '${result.record.id}'`]
120
69
  });
121
- ctx.state.set(state);
122
- ctx.down([
123
- [
124
- "DATA",
125
- Object.freeze({
126
- assertions: Object.freeze(draftProjection.assertions),
127
- status,
128
- errors,
129
- cursor
130
- })
131
- ]
132
- ]);
133
- },
134
- {
135
- name: `${name}/projection`,
136
- factory: "agenticMemoryKgProjection",
137
- completeWhenDepsComplete: false,
138
- errorWhenDepsError: false
70
+ continue;
139
71
  }
140
- );
141
- return {
142
- input: { records: opts.records, drafts: opts.drafts },
143
- projection,
144
- assertions: solutionProjection(
145
- graph,
146
- projection,
147
- `${name}/assertions`,
148
- "agenticMemoryKgAssertions",
149
- (fact) => fact.assertions
150
- ),
151
- status: solutionProjection(
152
- graph,
153
- projection,
154
- `${name}/status`,
155
- "agenticMemoryKgStatus",
156
- (fact) => fact.status
157
- ),
158
- errors: solutionProjection(
159
- graph,
160
- projection,
161
- `${name}/errors`,
162
- "agenticMemoryKgErrors",
163
- (fact) => fact.errors
164
- ),
165
- cursor: solutionProjection(
166
- graph,
167
- projection,
168
- `${name}/cursor`,
169
- "agenticMemoryKgCursor",
170
- (fact) => fact.cursor
171
- )
172
- };
173
- }
174
- function agenticMemoryRecordFrame(record) {
175
- const result = validateAndSnapshotRecord(record, 0);
176
- if (result.errors.length > 0 || result.record === void 0) {
177
- throw new TypeError(
178
- `agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
179
- );
72
+ if (seenFragmentIds.has(result.record.fragment.id)) {
73
+ invalidRecordIndexes.add(i);
74
+ errors.push({
75
+ code: "duplicate-fragment-id",
76
+ message: "agenticMemoryBundle: duplicate fragment id",
77
+ index: i,
78
+ recordId: result.record.id,
79
+ fragmentId: result.record.fragment.id,
80
+ record: raw,
81
+ validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
82
+ });
83
+ continue;
84
+ }
85
+ seenRecordIds.add(result.record.id);
86
+ seenFragmentIds.add(result.record.fragment.id);
87
+ records.push(result.record);
88
+ fragments.push(result.record.fragment);
89
+ metadataByFragmentId[result.record.fragment.id] = recordMetadata(result.record);
180
90
  }
181
- assertAgenticMemoryRecordCodecShape(record);
182
- assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
183
- return Object.freeze({
184
- format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
185
- version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
186
- record: Object.freeze({
187
- id: result.record.id,
188
- kind: result.record.kind,
189
- persistenceLevel: result.record.persistenceLevel,
190
- artifactKind: result.record.artifactKind,
191
- ...result.record.scope === void 0 ? {} : { scope: result.record.scope },
192
- fragment: fragmentFrame(result.record.fragment)
193
- })
194
- });
91
+ return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
195
92
  }
196
- function assertAgenticMemoryRecordFrame(value) {
197
- if (!isPlainRecord(value))
198
- throw new TypeError("agenticMemoryRecordFrame: frame must be an object");
199
- assertStrictJsonValue(value, "agenticMemoryRecordFrame");
200
- assertExactKeys(value, ["format", "record", "version"], "agenticMemoryRecordFrame");
201
- if (value.format !== AGENTIC_MEMORY_RECORD_FRAME_FORMAT) {
202
- throw new TypeError("agenticMemoryRecordFrame: invalid format");
93
+ function validateAndSnapshotRecord(value, index) {
94
+ try {
95
+ return validateAndSnapshotRecordInner(value, index);
96
+ } catch (error) {
97
+ return {
98
+ errors: [
99
+ {
100
+ code: "invalid-record",
101
+ message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
102
+ index,
103
+ record: value,
104
+ validationErrors: Object.freeze(["record access failed"])
105
+ }
106
+ ]
107
+ };
203
108
  }
204
- if (value.version !== AGENTIC_MEMORY_RECORD_FRAME_VERSION) {
205
- throw new TypeError("agenticMemoryRecordFrame: invalid version");
109
+ }
110
+ function validateAndSnapshotRecordInner(value, index) {
111
+ const errors = [];
112
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
113
+ return {
114
+ errors: [
115
+ {
116
+ code: "invalid-record",
117
+ message: "agenticMemoryBundle: record must be an object",
118
+ index,
119
+ record: value
120
+ }
121
+ ]
122
+ };
206
123
  }
207
- const rawRecord = value.record;
208
- if (!isPlainRecord(rawRecord)) {
209
- throw new TypeError("agenticMemoryRecordFrame: record must be an object");
124
+ const record = value;
125
+ const recordId = typeof record.id === "string" ? record.id : void 0;
126
+ if (recordId === void 0 || recordId.length === 0) {
127
+ errors.push({
128
+ code: "invalid-record",
129
+ message: "agenticMemoryBundle: record.id must be a non-empty string",
130
+ index,
131
+ record: value,
132
+ validationErrors: ["record.id must be a non-empty string"]
133
+ });
210
134
  }
211
- assertExactKeys(
212
- rawRecord,
213
- rawRecord.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
214
- "agenticMemoryRecordFrame.record"
215
- );
216
- const rawFragment = rawRecord.fragment;
217
- if (!isPlainRecord(rawFragment)) {
218
- throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
135
+ if (!isAgenticMemoryKind(record.kind)) {
136
+ errors.push({
137
+ code: "invalid-record-kind",
138
+ message: "agenticMemoryBundle: record.kind is invalid",
139
+ index,
140
+ recordId,
141
+ record: value,
142
+ validationErrors: ["kind must be one of working, episodic, semantic, procedural, profile"]
143
+ });
219
144
  }
220
- assertExactKeys(
221
- rawFragment,
222
- [
223
- "id",
224
- "payload",
225
- "tNs",
226
- ...rawFragment.validFrom === void 0 ? [] : ["validFrom"],
227
- ...rawFragment.validTo === void 0 ? [] : ["validTo"],
228
- "confidence",
229
- "tags",
230
- "sources",
231
- ...rawFragment.embedding === void 0 ? [] : ["embedding"],
232
- ...rawFragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
233
- ...rawFragment.provenance === void 0 ? [] : ["provenance"]
234
- ],
235
- "agenticMemoryRecordFrame.record.fragment"
236
- );
237
- if (rawRecord.scope !== void 0) assertScopeFrame(rawRecord.scope);
238
- const frame = value;
239
- const decoded = recordFromFrame(frame);
240
- const roundtrip = agenticMemoryRecordFrame(decoded);
241
- return roundtrip;
242
- }
243
- function agenticMemoryRecordFrameCodec() {
145
+ if (!isAgenticMemoryPersistenceLevel(record.persistenceLevel)) {
146
+ errors.push({
147
+ code: "invalid-persistence-level",
148
+ message: "agenticMemoryBundle: record.persistenceLevel is invalid",
149
+ index,
150
+ recordId,
151
+ record: value,
152
+ validationErrors: [
153
+ "persistenceLevel must be one of turn, session, project, longTerm, permanent, archived"
154
+ ]
155
+ });
156
+ }
157
+ if (!isAgenticMemoryArtifactKind(record.artifactKind)) {
158
+ errors.push({
159
+ code: "invalid-artifact-kind",
160
+ message: "agenticMemoryBundle: record.artifactKind is invalid",
161
+ index,
162
+ recordId,
163
+ record: value,
164
+ validationErrors: ["artifactKind must be one of raw, insight, profile, procedure"]
165
+ });
166
+ }
167
+ const scopeValidation = validateScope(record.scope);
168
+ if (!scopeValidation.ok) {
169
+ errors.push({
170
+ code: "invalid-scope",
171
+ message: "agenticMemoryBundle: record.scope is invalid",
172
+ index,
173
+ recordId,
174
+ record: value,
175
+ validationErrors: Object.freeze(scopeValidation.errors)
176
+ });
177
+ }
178
+ const fragmentValidation = validateMemoryFragment(record.fragment);
179
+ if (!fragmentValidation.ok) {
180
+ errors.push({
181
+ code: "invalid-fragment",
182
+ message: "agenticMemoryBundle: record.fragment is invalid",
183
+ index,
184
+ recordId,
185
+ fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
186
+ record: value,
187
+ validationErrors: Object.freeze([...fragmentValidation.errors])
188
+ });
189
+ }
190
+ const forbiddenFields = [
191
+ "storageTier",
192
+ "storageKey",
193
+ "adapter",
194
+ "collection",
195
+ "collections",
196
+ "ttl",
197
+ "ttlMs",
198
+ "ttlNs",
199
+ "expiresAt",
200
+ "timer",
201
+ "scheduler",
202
+ "schedule",
203
+ "retentionTimer",
204
+ "consolidationSchedule",
205
+ "reflectionSchedule",
206
+ "llm",
207
+ "llmHandle",
208
+ "tool",
209
+ "toolHandle",
210
+ "runner",
211
+ "runnerHandle",
212
+ "restore",
213
+ "hydrate",
214
+ "hydration",
215
+ "graphMutation",
216
+ "protocol"
217
+ ];
218
+ const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
219
+ if (presentForbidden.length > 0) {
220
+ errors.push({
221
+ code: "invalid-record",
222
+ message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
223
+ index,
224
+ recordId,
225
+ record: value,
226
+ validationErrors: Object.freeze(
227
+ presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
228
+ )
229
+ });
230
+ }
231
+ if (errors.length > 0) return { errors };
232
+ const scope = scopeValidation.scope;
233
+ const fragment = snapshotFragment(record.fragment);
244
234
  return {
245
- encode(value) {
246
- return strictJsonCodec.encode(assertAgenticMemoryRecordFrame(value));
247
- },
248
- decode(bytes) {
249
- return assertAgenticMemoryRecordFrame(strictJsonCodec.decode(bytes));
250
- }
235
+ record: Object.freeze({
236
+ id: recordId,
237
+ kind: record.kind,
238
+ persistenceLevel: record.persistenceLevel,
239
+ artifactKind: record.artifactKind,
240
+ ...scope === void 0 ? {} : { scope },
241
+ fragment
242
+ }),
243
+ errors
251
244
  };
252
245
  }
253
- function agenticMemoryRecordCodec() {
254
- const frameCodec = agenticMemoryRecordFrameCodec();
255
- return {
256
- encode(value) {
257
- return frameCodec.encode(agenticMemoryRecordFrame(value));
258
- },
259
- decode(bytes) {
260
- return recordFromFrame(frameCodec.decode(bytes));
261
- }
262
- };
246
+ function snapshotFragment(fragment) {
247
+ return Object.freeze({
248
+ id: fragment.id,
249
+ payload: fragment.payload,
250
+ tNs: fragment.tNs,
251
+ ...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
252
+ ...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
253
+ confidence: fragment.confidence,
254
+ tags: Object.freeze([...fragment.tags]),
255
+ sources: Object.freeze([...fragment.sources]),
256
+ ...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
257
+ ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
258
+ ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
259
+ });
263
260
  }
264
- function agenticMemoryRetentionBundle(graph, opts) {
265
- const name = opts.name ?? "agenticMemoryRetention";
266
- const projection = graph.node(
267
- [opts.records, opts.commands],
268
- (ctx) => {
269
- const state = ctx.state.get() ?? { evaluation: 0 };
270
- state.evaluation += 1;
271
- const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
272
- const retention = projectRetention(depLatest(ctx, 1), recordProjection.records);
273
- const cursor = Object.freeze({
274
- evaluation: state.evaluation,
275
- validRecords: recordProjection.records.length,
276
- validCommands: retention.validCommands,
277
- invalidCommands: retention.invalidCommands,
278
- activeRecords: retention.activeRecords.length,
279
- archivedRecords: retention.archivedRecords.length,
280
- consolidationRequests: retention.consolidationRequests.length
281
- });
282
- const errors = Object.freeze(
283
- [...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
284
- (error) => freezeError({ ...error, cursor })
285
- )
286
- );
287
- const status = Object.freeze({
288
- state: agenticStatusState(errors.length, recordProjection.records.length),
289
- cursor
290
- });
291
- ctx.state.set(state);
292
- ctx.down([
293
- [
294
- "DATA",
295
- Object.freeze({
296
- activeRecords: Object.freeze(retention.activeRecords),
297
- archivedRecords: Object.freeze(retention.archivedRecords),
298
- consolidationRequests: Object.freeze(retention.consolidationRequests),
299
- status,
300
- errors,
301
- cursor
302
- })
303
- ]
304
- ]);
305
- },
306
- {
307
- name: `${name}/projection`,
308
- factory: "agenticMemoryRetention",
309
- completeWhenDepsComplete: false,
310
- errorWhenDepsError: false
261
+ function recordMetadata(record) {
262
+ return Object.freeze({
263
+ recordId: record.id,
264
+ kind: record.kind,
265
+ persistenceLevel: record.persistenceLevel,
266
+ artifactKind: record.artifactKind,
267
+ ...record.scope === void 0 ? {} : { scope: record.scope }
268
+ });
269
+ }
270
+ function validateRecordMetadata(value) {
271
+ if (value === void 0) return { ok: true, errors: [] };
272
+ if (!isPlainRecord(value)) {
273
+ return { ok: false, errors: ["record metadata must be an object when present"] };
274
+ }
275
+ const errors = [];
276
+ for (const key of Object.keys(value)) {
277
+ if (key !== "recordId" && key !== "kind" && key !== "persistenceLevel" && key !== "artifactKind" && key !== "scope") {
278
+ errors.push(`record.${key} is not part of AgenticMemoryRecordMetadata`);
311
279
  }
312
- );
280
+ }
281
+ if (!isNonEmptyString(value.recordId)) {
282
+ errors.push("record.recordId must be a non-empty string");
283
+ }
284
+ if (!isAgenticMemoryKind(value.kind)) {
285
+ errors.push("record.kind is invalid");
286
+ }
287
+ if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
288
+ errors.push("record.persistenceLevel is invalid");
289
+ }
290
+ if (!isAgenticMemoryArtifactKind(value.artifactKind)) {
291
+ errors.push("record.artifactKind is invalid");
292
+ }
293
+ const scopeValidation = validateScope(value.scope);
294
+ if (!scopeValidation.ok) {
295
+ errors.push(...scopeValidation.errors.map((error) => `record.${error}`));
296
+ }
297
+ if (errors.length > 0) return { ok: false, errors };
313
298
  return {
314
- input: { records: opts.records, commands: opts.commands },
315
- projection,
316
- activeRecords: solutionProjection(
317
- graph,
318
- projection,
319
- `${name}/activeRecords`,
320
- "agenticMemoryRetentionActiveRecords",
321
- (fact) => fact.activeRecords
322
- ),
323
- archivedRecords: solutionProjection(
324
- graph,
325
- projection,
326
- `${name}/archivedRecords`,
327
- "agenticMemoryRetentionArchivedRecords",
328
- (fact) => fact.archivedRecords
329
- ),
330
- consolidationRequests: solutionProjection(
331
- graph,
332
- projection,
333
- `${name}/consolidationRequests`,
334
- "agenticMemoryRetentionConsolidationRequests",
335
- (fact) => fact.consolidationRequests
336
- ),
337
- status: solutionProjection(
338
- graph,
339
- projection,
340
- `${name}/status`,
341
- "agenticMemoryRetentionStatus",
342
- (fact) => fact.status
343
- ),
344
- errors: solutionProjection(
345
- graph,
346
- projection,
347
- `${name}/errors`,
348
- "agenticMemoryRetentionErrors",
349
- (fact) => fact.errors
350
- ),
351
- cursor: solutionProjection(
352
- graph,
353
- projection,
354
- `${name}/cursor`,
355
- "agenticMemoryRetentionCursor",
356
- (fact) => fact.cursor
357
- )
299
+ ok: true,
300
+ errors,
301
+ metadata: Object.freeze({
302
+ recordId: value.recordId,
303
+ kind: value.kind,
304
+ persistenceLevel: value.persistenceLevel,
305
+ artifactKind: value.artifactKind,
306
+ ...scopeValidation.scope === void 0 ? {} : { scope: scopeValidation.scope }
307
+ })
358
308
  };
359
309
  }
360
- function agenticMemoryConsolidationBundle(graph, opts) {
361
- const name = opts.name ?? "agenticMemoryConsolidation";
362
- const projection = graph.node(
363
- [opts.records, opts.requests, opts.outcomes],
364
- (ctx) => {
365
- const state = ctx.state.get() ?? { evaluation: 0 };
366
- state.evaluation += 1;
367
- const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
368
- const requests = validateConsolidationRequests(depLatest(ctx, 1), recordProjection.records);
369
- const outcomes = projectConsolidationOutcomes(
370
- depLatest(ctx, 2),
371
- requests.requests,
372
- state.evaluation
373
- );
374
- const cursor = Object.freeze({
375
- evaluation: state.evaluation,
376
- validRequests: requests.requests.length,
377
- validOutcomes: outcomes.validOutcomes,
378
- invalidOutcomes: outcomes.invalidOutcomes,
379
- results: outcomes.results.length,
380
- proposedRecordDrafts: outcomes.proposedRecordDrafts.length
381
- });
382
- const errors = Object.freeze(
383
- [
384
- ...recordProjection.errors.map(consolidationErrorFromRecordError),
385
- ...requests.errors.map(consolidationErrorFromRetentionError),
386
- ...outcomes.errors
387
- ].map((error) => freezeError({ ...error, cursor }))
388
- );
389
- const status = Object.freeze({
390
- state: agenticStatusState(errors.length, outcomes.results.length),
391
- cursor
392
- });
393
- ctx.state.set(state);
394
- ctx.down([
395
- [
396
- "DATA",
397
- Object.freeze({
398
- results: Object.freeze(outcomes.results),
399
- proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
400
- commands: Object.freeze(outcomes.commands),
401
- status,
402
- errors,
403
- cursor
404
- })
405
- ]
406
- ]);
407
- },
408
- {
409
- name: `${name}/projection`,
410
- factory: "agenticMemoryConsolidation",
411
- completeWhenDepsComplete: false,
412
- errorWhenDepsError: false
310
+ function contextState(projection, retrieval) {
311
+ if (projection === "error" || retrieval === "error") return "error";
312
+ if (projection === "partial" || retrieval === "partial") return "partial";
313
+ return retrieval;
314
+ }
315
+ function agenticStatusState(errorCount, validRecords) {
316
+ if (errorCount > 0 && validRecords === 0) return "error";
317
+ if (errorCount > 0) return "partial";
318
+ return validRecords > 0 ? "ready" : "empty";
319
+ }
320
+ function isAgenticMemoryKind(value) {
321
+ return value === "working" || value === "episodic" || value === "semantic" || value === "procedural" || value === "profile";
322
+ }
323
+ function isAgenticMemoryPersistenceLevel(value) {
324
+ return value === "turn" || value === "session" || value === "project" || value === "longTerm" || value === "permanent" || value === "archived";
325
+ }
326
+ function isAgenticMemoryArtifactKind(value) {
327
+ return value === "raw" || value === "insight" || value === "profile" || value === "procedure";
328
+ }
329
+ function validateScope(value) {
330
+ if (value === void 0) return { ok: true, errors: [] };
331
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
332
+ return { ok: false, errors: ["scope must be an object when present"] };
333
+ }
334
+ const scope = value;
335
+ const errors = [];
336
+ const allowed = /* @__PURE__ */ new Set(["sessionId", "projectId", "userId", "tenantId"]);
337
+ for (const key of Object.keys(scope)) {
338
+ if (!allowed.has(key)) errors.push(`scope.${key} is not part of AgenticMemoryScope`);
339
+ }
340
+ for (const key of allowed) {
341
+ if (scope[key] !== void 0 && (typeof scope[key] !== "string" || scope[key].length === 0)) {
342
+ errors.push(`scope.${key} must be a non-empty string when present`);
413
343
  }
414
- );
344
+ }
345
+ if (errors.length > 0) return { ok: false, errors };
415
346
  return {
416
- input: { records: opts.records, requests: opts.requests, outcomes: opts.outcomes },
417
- projection,
418
- results: solutionProjection(
419
- graph,
420
- projection,
421
- `${name}/results`,
422
- "agenticMemoryConsolidationResults",
423
- (fact) => fact.results
424
- ),
425
- proposedRecordDrafts: solutionProjection(
426
- graph,
427
- projection,
428
- `${name}/proposedRecordDrafts`,
429
- "agenticMemoryConsolidationRecordDrafts",
430
- (fact) => fact.proposedRecordDrafts
431
- ),
432
- commands: solutionProjection(
433
- graph,
434
- projection,
435
- `${name}/commands`,
436
- "agenticMemoryConsolidationCommands",
437
- (fact) => fact.commands
438
- ),
439
- status: solutionProjection(
440
- graph,
441
- projection,
442
- `${name}/status`,
443
- "agenticMemoryConsolidationStatus",
444
- (fact) => fact.status
445
- ),
446
- errors: solutionProjection(
447
- graph,
448
- projection,
449
- `${name}/errors`,
450
- "agenticMemoryConsolidationErrors",
451
- (fact) => fact.errors
452
- ),
453
- cursor: solutionProjection(
454
- graph,
455
- projection,
456
- `${name}/cursor`,
457
- "agenticMemoryConsolidationCursor",
458
- (fact) => fact.cursor
459
- )
347
+ ok: true,
348
+ errors,
349
+ scope: Object.freeze({
350
+ ...scope.sessionId === void 0 ? {} : { sessionId: scope.sessionId },
351
+ ...scope.projectId === void 0 ? {} : { projectId: scope.projectId },
352
+ ...scope.userId === void 0 ? {} : { userId: scope.userId },
353
+ ...scope.tenantId === void 0 ? {} : { tenantId: scope.tenantId }
354
+ })
460
355
  };
461
356
  }
462
- function agenticMemoryContextPackingBundle(graph, opts) {
463
- const name = opts.name ?? "agenticMemoryContextPacking";
464
- const projection = graph.node(
465
- [opts.context, opts.texts, opts.policy],
466
- (ctx) => {
467
- const state = ctx.state.get() ?? { evaluation: 0 };
468
- state.evaluation += 1;
469
- const packed = packContext(
470
- depLatest(ctx, 0),
471
- depLatest(ctx, 1),
472
- depLatest(ctx, 2),
473
- state.evaluation
474
- );
475
- ctx.state.set(state);
476
- ctx.down([["DATA", packed]]);
477
- },
478
- {
479
- name: `${name}/projection`,
480
- factory: "agenticMemoryContextPacking",
481
- completeWhenDepsComplete: false,
482
- errorWhenDepsError: false
483
- }
357
+ function isPlainRecord(value) {
358
+ return value !== null && typeof value === "object" && !Array.isArray(value);
359
+ }
360
+ function ownKeys(value) {
361
+ return Object.keys(value).sort();
362
+ }
363
+ function assertExactKeys(value, expected, label) {
364
+ const actual = ownKeys(value);
365
+ const want = [...expected].sort();
366
+ if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
367
+ throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
368
+ }
369
+ }
370
+ function assertAgenticMemoryRecordCodecShape(value) {
371
+ if (!isPlainRecord(value)) {
372
+ throw new TypeError("agenticMemoryRecordFrame: record must be an object");
373
+ }
374
+ assertNoSymbolKeys(value, "agenticMemoryRecordFrame.record");
375
+ assertExactKeys(
376
+ value,
377
+ value.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
378
+ "agenticMemoryRecordFrame.record"
484
379
  );
485
- return {
486
- input: { context: opts.context, texts: opts.texts, policy: opts.policy },
487
- projection,
488
- packedContext: solutionProjection(
489
- graph,
490
- projection,
491
- `${name}/packedContext`,
492
- "agenticMemoryPackedContext",
493
- (fact) => fact.packedContext
494
- ),
495
- status: solutionProjection(
496
- graph,
497
- projection,
498
- `${name}/status`,
499
- "agenticMemoryContextPackingStatus",
500
- (fact) => fact.status
501
- ),
502
- errors: solutionProjection(
503
- graph,
504
- projection,
505
- `${name}/errors`,
506
- "agenticMemoryContextPackingErrors",
507
- (fact) => fact.errors
508
- ),
509
- cursor: solutionProjection(
510
- graph,
511
- projection,
512
- `${name}/cursor`,
513
- "agenticMemoryContextPackingCursor",
514
- (fact) => fact.cursor
515
- )
516
- };
380
+ const fragment = value.fragment;
381
+ if (!isPlainRecord(fragment)) {
382
+ throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
383
+ }
384
+ assertNoSymbolKeys(fragment, "agenticMemoryRecordFrame.record.fragment");
385
+ assertExactKeys(
386
+ fragment,
387
+ [
388
+ "id",
389
+ "payload",
390
+ "tNs",
391
+ ...fragment.validFrom === void 0 ? [] : ["validFrom"],
392
+ ...fragment.validTo === void 0 ? [] : ["validTo"],
393
+ "confidence",
394
+ "tags",
395
+ "sources",
396
+ ...fragment.embedding === void 0 ? [] : ["embedding"],
397
+ ...fragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
398
+ ...fragment.provenance === void 0 ? [] : ["provenance"]
399
+ ],
400
+ "agenticMemoryRecordFrame.record.fragment"
401
+ );
402
+ assertStrictJsonValue(fragment.tags, "record.fragment.tags");
403
+ assertStrictJsonValue(fragment.sources, "record.fragment.sources");
404
+ if (fragment.embedding !== void 0) {
405
+ assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
406
+ }
407
+ if (value.scope !== void 0) assertScopeFrame(value.scope);
408
+ }
409
+ function assertNoSymbolKeys(value, label) {
410
+ if (Object.getOwnPropertySymbols(value).length > 0) {
411
+ throw new TypeError(`${label}: unexpected symbol fields`);
412
+ }
413
+ }
414
+ function decimalBigIntString(value, label) {
415
+ const out = value.toString(10);
416
+ if (!/^-?(0|[1-9]\d*)$/.test(out)) {
417
+ throw new TypeError(`${label} must encode as a canonical decimal bigint string`);
418
+ }
419
+ return out;
420
+ }
421
+ function parseDecimalBigInt(value, label) {
422
+ if (typeof value !== "string" || !/^(0|-?[1-9]\d*)$/.test(value)) {
423
+ throw new TypeError(`${label} must be a canonical decimal bigint string`);
424
+ }
425
+ return BigInt(value);
426
+ }
427
+ function assertStrictJsonValue(value, label) {
428
+ try {
429
+ strictJsonCodec.encode(value);
430
+ return value;
431
+ } catch (error) {
432
+ throw new TypeError(`${label} must be strict JSON: ${errorMessage(error)}`);
433
+ }
434
+ }
435
+ function assertScopeFrame(value) {
436
+ if (!isPlainRecord(value)) {
437
+ throw new TypeError("agenticMemoryRecordFrame: scope must be an object when present");
438
+ }
439
+ assertStrictJsonValue(value, "record.scope");
440
+ const validation = validateScope(value);
441
+ if (!validation.ok || validation.scope === void 0) {
442
+ throw new TypeError(`agenticMemoryRecordFrame: invalid scope: ${validation.errors.join("; ")}`);
443
+ }
444
+ assertExactKeys(
445
+ value,
446
+ [
447
+ ...value.sessionId === void 0 ? [] : ["sessionId"],
448
+ ...value.projectId === void 0 ? [] : ["projectId"],
449
+ ...value.userId === void 0 ? [] : ["userId"],
450
+ ...value.tenantId === void 0 ? [] : ["tenantId"]
451
+ ],
452
+ "agenticMemoryRecordFrame.record.scope"
453
+ );
454
+ return validation.scope;
455
+ }
456
+ function assertKindValue(value) {
457
+ if (!isAgenticMemoryKind(value)) {
458
+ throw new TypeError("agenticMemoryRecordFrame: invalid memory kind");
459
+ }
460
+ return value;
461
+ }
462
+ function assertPersistenceLevelValue(value) {
463
+ if (!isAgenticMemoryPersistenceLevel(value)) {
464
+ throw new TypeError("agenticMemoryRecordFrame: invalid persistence level");
465
+ }
466
+ return value;
467
+ }
468
+ function assertArtifactKindValue(value) {
469
+ if (!isAgenticMemoryArtifactKind(value)) {
470
+ throw new TypeError("agenticMemoryRecordFrame: invalid artifact kind");
471
+ }
472
+ return value;
473
+ }
474
+ function assertNonEmptyString(value, label) {
475
+ if (!isNonEmptyString(value)) throw new TypeError(`${label} must be a non-empty string`);
476
+ return value;
477
+ }
478
+ function assertString(value, label) {
479
+ if (typeof value !== "string") throw new TypeError(`${label} must be a string`);
480
+ return value;
481
+ }
482
+ function assertConfidence(value, label) {
483
+ if (!Number.isFinite(value) || value < 0 || value > 1) {
484
+ throw new TypeError(`${label} must be a finite number in [0, 1]`);
485
+ }
486
+ return value;
487
+ }
488
+ function assertStringArray(value, label) {
489
+ if (!isDenseArrayOf(value, (item) => typeof item === "string")) {
490
+ throw new TypeError(`${label} must be a readonly string array`);
491
+ }
492
+ return Object.freeze([...value]);
493
+ }
494
+ function assertFiniteNumberArray(value, label) {
495
+ if (!isDenseArrayOf(value, (item) => Number.isFinite(item))) {
496
+ throw new TypeError(`${label} must be a finite number array`);
497
+ }
498
+ return Object.freeze([...value]);
499
+ }
500
+ function isNonEmptyString(value) {
501
+ return typeof value === "string" && value.length > 0;
502
+ }
503
+ function isDenseArrayOf(value, predicate) {
504
+ if (!Array.isArray(value)) return false;
505
+ for (let i = 0; i < value.length; i += 1) {
506
+ if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
507
+ }
508
+ return true;
509
+ }
510
+ function freezeError(error) {
511
+ return Object.freeze({
512
+ ...error,
513
+ ...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) }
514
+ });
515
+ }
516
+ function safeArrayLength(value) {
517
+ try {
518
+ return value.length;
519
+ } catch {
520
+ return void 0;
521
+ }
522
+ }
523
+ function errorMessage(error) {
524
+ return error instanceof Error ? error.message : String(error);
517
525
  }
526
+
527
+ // src/solutions/agentic-memory-projection.ts
518
528
  function solutionProjection(graph, snapshot, name, factory, select) {
519
529
  return graph.node(
520
530
  [snapshot],
@@ -642,569 +652,187 @@ function agenticMemoryRecordProjection(graph, records, name) {
642
652
  }
643
653
  );
644
654
  }
645
- function validateAndProjectKgDrafts(value, records) {
646
- const assertions = [];
647
- const errors = [];
648
- let invalidDrafts = 0;
649
- if (!Array.isArray(value)) {
650
- return {
651
- assertions,
652
- invalidDrafts: 1,
653
- errors: [
654
- {
655
- code: "invalid-drafts-input",
656
- message: "agenticMemoryKgProjectionBundle: drafts input must be an array",
657
- draft: value
658
- }
659
- ]
660
- };
661
- }
662
- const length = safeArrayLength(value);
663
- if (length === void 0) {
664
- return {
665
- assertions,
666
- invalidDrafts: 1,
667
- errors: [
668
- {
669
- code: "invalid-drafts-input",
670
- message: "agenticMemoryKgProjectionBundle: drafts input length could not be read",
671
- draft: value
672
- }
673
- ]
674
- };
675
- }
676
- const recordById = new Map(records.map((record) => [record.id, record]));
677
- const fragmentToRecord = new Map(records.map((record) => [record.fragment.id, record.id]));
678
- const seenAssertions = /* @__PURE__ */ new Set();
679
- for (let i = 0; i < length; i += 1) {
680
- let raw;
681
- try {
682
- raw = value[i];
683
- const result = validateKgDraft(raw, i);
684
- if (result.errors.length > 0 || result.draft === void 0) {
685
- invalidDrafts += 1;
686
- errors.push(...result.errors);
687
- continue;
688
- }
689
- const draft = result.draft;
690
- if (seenAssertions.has(draft.id)) {
691
- invalidDrafts += 1;
692
- errors.push({
693
- code: "duplicate-assertion-id",
694
- message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
695
- index: i,
696
- assertionId: draft.id,
697
- recordId: draft.recordId,
698
- fragmentId: draft.fragmentId,
699
- draft: raw,
700
- validationErrors: [`duplicate assertion id '${draft.id}'`]
701
- });
702
- continue;
703
- }
704
- const record = recordById.get(draft.recordId);
705
- if (record === void 0) {
706
- invalidDrafts += 1;
707
- errors.push({
708
- code: "missing-record-ref",
709
- message: "agenticMemoryKgProjectionBundle: draft references a missing record",
710
- index: i,
711
- assertionId: draft.id,
712
- recordId: draft.recordId,
713
- fragmentId: draft.fragmentId,
714
- draft: raw,
715
- validationErrors: [`record '${draft.recordId}' is not projected`]
716
- });
717
- continue;
718
- }
719
- const owner = fragmentToRecord.get(draft.fragmentId);
720
- if (owner === void 0) {
721
- invalidDrafts += 1;
722
- errors.push({
723
- code: "missing-fragment-ref",
724
- message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
725
- index: i,
726
- assertionId: draft.id,
727
- recordId: draft.recordId,
728
- fragmentId: draft.fragmentId,
729
- draft: raw,
730
- validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
731
- });
732
- continue;
733
- }
734
- if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
735
- invalidDrafts += 1;
736
- errors.push({
737
- code: "fragment-record-mismatch",
738
- message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
739
- index: i,
740
- assertionId: draft.id,
741
- recordId: draft.recordId,
742
- fragmentId: draft.fragmentId,
743
- draft: raw,
744
- validationErrors: [
745
- `fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
746
- ]
747
- });
748
- continue;
749
- }
750
- seenAssertions.add(draft.id);
751
- assertions.push(
752
- Object.freeze({
753
- id: draft.id,
754
- recordId: draft.recordId,
755
- fragmentId: draft.fragmentId,
756
- subject: draft.subject,
757
- predicate: draft.predicate,
758
- object: draft.object,
759
- ...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
760
- sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
761
- ...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
762
- })
763
- );
764
- } catch (error) {
765
- invalidDrafts += 1;
766
- errors.push({
767
- code: "invalid-draft",
768
- message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage(error)}`,
769
- index: i,
770
- draft: raw,
771
- validationErrors: ["draft access failed"]
772
- });
773
- }
774
- }
775
- return { assertions, errors, invalidDrafts };
776
- }
777
- function validateKgDraft(value, index) {
778
- const errors = [];
779
- if (!isPlainRecord(value)) {
780
- return {
781
- errors: [
782
- {
783
- code: "invalid-draft",
784
- message: "agenticMemoryKgProjectionBundle: draft must be an object",
785
- index,
786
- draft: value
787
- }
788
- ]
789
- };
790
- }
791
- const raw = value;
792
- const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
793
- const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
794
- const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
795
- const subject = validateAssertionSubject(raw.subject);
796
- const object = validateAssertionObject(raw.object);
797
- const shapeErrors = [];
798
- if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
799
- if (recordId === void 0) {
800
- shapeErrors.push("draft.recordId must be a non-empty string");
801
- }
802
- if (fragmentId === void 0) {
803
- shapeErrors.push("draft.fragmentId must be a non-empty string");
804
- }
805
- shapeErrors.push(...subject.errors);
806
- if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
807
- shapeErrors.push("draft.predicate must be a non-empty string");
808
- }
809
- shapeErrors.push(...object.errors);
810
- if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
811
- shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
812
- }
813
- if (raw.sources !== void 0 && !isDenseArrayOf(raw.sources, isNonEmptyString)) {
814
- shapeErrors.push("draft.sources must be a readonly string array");
815
- }
816
- if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
817
- shapeErrors.push("draft.provenance must be a string when present");
818
- }
819
- if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
820
- if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
821
- return { errors };
822
- }
823
- return {
824
- draft: Object.freeze({
825
- id,
826
- recordId,
827
- fragmentId,
828
- subject: subject.subject,
829
- predicate: raw.predicate,
830
- object: object.object,
831
- ...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
832
- ...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
833
- ...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
834
- }),
835
- errors
836
- };
837
- }
838
- function validateAssertionSubject(value) {
839
- if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
840
- const id = value.id;
841
- const type = value.type;
842
- const errors = [];
843
- if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
844
- if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
845
- errors.push("subject.type must be a non-empty string when present");
846
- }
847
- if (errors.length > 0) return { errors };
848
- return {
849
- subject: Object.freeze({
850
- id,
851
- ...type === void 0 ? {} : { type }
852
- }),
853
- errors
854
- };
855
- }
856
- function validateAssertionObject(value) {
857
- if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
858
- const kind = value.kind;
859
- const errors = [];
860
- if (kind === "entity") {
861
- if (typeof value.id !== "string" || value.id.length === 0) {
862
- errors.push("object.id must be non-empty for entity objects");
863
- }
864
- if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
865
- errors.push("object.type must be a non-empty string when present");
866
- }
867
- if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
868
- if (errors.length > 0) return { errors };
869
- return {
870
- object: Object.freeze({
871
- kind: "entity",
872
- id: value.id,
873
- ...value.type === void 0 ? {} : { type: value.type }
874
- }),
875
- errors
876
- };
877
- }
878
- if (kind === "value") {
879
- if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
880
- else {
881
- try {
882
- assertStrictJsonValue(value.value, "object.value");
883
- } catch (error) {
884
- errors.push(errorMessage(error));
885
- }
886
- }
887
- if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
888
- errors.push("object.valueType must be a non-empty string when present");
889
- }
890
- if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
891
- if (errors.length > 0) return { errors };
892
- return {
893
- object: Object.freeze({
894
- kind: "value",
895
- value: value.value,
896
- ...value.valueType === void 0 ? {} : { valueType: value.valueType }
897
- }),
898
- errors
899
- };
900
- }
901
- return { errors: ["object.kind must be entity or value"] };
902
- }
903
- function kgShapeError(index, draft, ...validationErrors) {
904
- return {
905
- code: "invalid-assertion-shape",
906
- message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
907
- index,
908
- draft,
909
- validationErrors: Object.freeze([...validationErrors])
910
- };
911
- }
912
- function kgErrorFromRecordError(error) {
913
- return {
914
- ...error,
915
- code: error.code
916
- };
917
- }
918
- function fragmentFrame(fragment) {
919
- return Object.freeze({
920
- id: fragment.id,
921
- payload: fragment.payload,
922
- tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
923
- ...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
924
- ...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
925
- confidence: fragment.confidence,
926
- tags: Object.freeze([...fragment.tags]),
927
- sources: Object.freeze([...fragment.sources]),
928
- ...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
929
- ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
930
- ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
655
+
656
+ // src/solutions/agentic-memory-bundle.ts
657
+ function agenticMemoryBundle(graph, opts) {
658
+ const name = opts.name ?? "agenticMemory";
659
+ const projection = agenticMemoryRecordProjection(graph, opts.records, `${name}/projection`);
660
+ const projectedRecords = agenticMemoryProjection(
661
+ graph,
662
+ projection,
663
+ `${name}/records`,
664
+ "agenticMemoryRecords",
665
+ (fact) => fact.records
666
+ );
667
+ const projectedFragments = agenticMemoryProjection(
668
+ graph,
669
+ projection,
670
+ `${name}/fragments`,
671
+ "agenticMemoryFragments",
672
+ (fact) => fact.fragments
673
+ );
674
+ const status = agenticMemoryProjection(
675
+ graph,
676
+ projection,
677
+ `${name}/status`,
678
+ "agenticMemoryStatus",
679
+ (fact) => fact.status
680
+ );
681
+ const errors = agenticMemoryProjection(
682
+ graph,
683
+ projection,
684
+ `${name}/errors`,
685
+ "agenticMemoryErrors",
686
+ (fact) => fact.errors
687
+ );
688
+ const retrieval = memoryRetrievalBundle(graph, {
689
+ name: `${name}/retrieval`,
690
+ fragments: projectedFragments,
691
+ query: opts.query
931
692
  });
932
- }
933
- function recordFromFrame(frame) {
934
- const fragment = frame.record.fragment;
935
- const record = {
936
- id: assertNonEmptyString(frame.record.id, "record.id"),
937
- kind: assertKindValue(frame.record.kind),
938
- persistenceLevel: assertPersistenceLevelValue(frame.record.persistenceLevel),
939
- artifactKind: assertArtifactKindValue(frame.record.artifactKind),
940
- ...frame.record.scope === void 0 ? {} : { scope: assertScopeFrame(frame.record.scope) },
941
- fragment: {
942
- id: assertNonEmptyString(fragment.id, "fragment.id"),
943
- payload: assertStrictJsonValue(fragment.payload, "fragment.payload"),
944
- tNs: parseDecimalBigInt(fragment.tNs, "fragment.tNs"),
945
- ...fragment.validFrom === void 0 ? {} : { validFrom: parseDecimalBigInt(fragment.validFrom, "fragment.validFrom") },
946
- ...fragment.validTo === void 0 ? {} : { validTo: parseDecimalBigInt(fragment.validTo, "fragment.validTo") },
947
- confidence: assertConfidence(fragment.confidence, "fragment.confidence"),
948
- tags: assertStringArray(fragment.tags, "fragment.tags"),
949
- sources: assertStringArray(fragment.sources, "fragment.sources"),
950
- ...fragment.embedding === void 0 ? {} : { embedding: assertFiniteNumberArray(fragment.embedding, "fragment.embedding") },
951
- ...fragment.parentFragmentId === void 0 ? {} : {
952
- parentFragmentId: assertNonEmptyString(fragment.parentFragmentId, "parentFragmentId")
953
- },
954
- ...fragment.provenance === void 0 ? {} : { provenance: assertString(fragment.provenance, "provenance") }
955
- }
956
- };
957
- const result = validateAndSnapshotRecord(record, 0);
958
- if (result.errors.length > 0 || result.record === void 0) {
959
- throw new TypeError(
960
- `agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
961
- );
962
- }
963
- return result.record;
964
- }
965
- function projectRetention(value, records) {
966
- const byId = new Map(records.map((record) => [record.id, record]));
967
- const view = new Map(records.map((record) => [record.id, record]));
968
- const requests = [];
969
- const errors = [];
970
- let validCommands = 0;
971
- let invalidCommands = 0;
972
- if (!Array.isArray(value)) {
973
- return {
974
- activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
975
- archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
976
- consolidationRequests: requests,
977
- validCommands,
978
- invalidCommands: 1,
979
- errors: [
980
- {
981
- code: "invalid-commands-input",
982
- message: "agenticMemoryRetentionBundle: commands input must be an array",
983
- command: value
984
- }
985
- ]
986
- };
987
- }
988
- const length = safeArrayLength(value);
989
- if (length === void 0) {
990
- return {
991
- activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
992
- archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
993
- consolidationRequests: requests,
994
- validCommands,
995
- invalidCommands: 1,
996
- errors: [
997
- {
998
- code: "invalid-commands-input",
999
- message: "agenticMemoryRetentionBundle: commands input length could not be read",
1000
- command: value
1001
- }
1002
- ]
1003
- };
1004
- }
1005
- const seenCommands = /* @__PURE__ */ new Set();
1006
- for (let i = 0; i < length; i += 1) {
1007
- let raw;
1008
- try {
1009
- raw = value[i];
1010
- const result = validateRetentionCommand(raw, i);
1011
- if (result.errors.length > 0 || result.command === void 0) {
1012
- invalidCommands += 1;
1013
- errors.push(...result.errors);
1014
- continue;
1015
- }
1016
- const command = result.command;
1017
- if (seenCommands.has(command.id)) {
1018
- invalidCommands += 1;
1019
- errors.push({
1020
- code: "duplicate-command-id",
1021
- message: "agenticMemoryRetentionBundle: duplicate command id",
1022
- index: i,
1023
- commandId: command.id,
1024
- command: raw,
1025
- validationErrors: [`duplicate command id '${command.id}'`]
1026
- });
1027
- continue;
1028
- }
1029
- const missing = retentionMissingRecords(command, byId);
1030
- if (missing.length > 0) {
1031
- invalidCommands += 1;
1032
- errors.push({
1033
- code: "missing-record-ref",
1034
- message: "agenticMemoryRetentionBundle: command references missing records",
1035
- index: i,
1036
- commandId: command.id,
1037
- recordId: "recordId" in command ? command.recordId : void 0,
1038
- recordIds: Object.freeze(missing),
1039
- command: raw,
1040
- validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
1041
- });
1042
- continue;
1043
- }
1044
- seenCommands.add(command.id);
1045
- validCommands += 1;
1046
- applyRetentionCommand(command, byId, view, requests);
1047
- } catch (error) {
1048
- invalidCommands += 1;
1049
- errors.push({
1050
- code: "invalid-command",
1051
- message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage(error)}`,
1052
- index: i,
1053
- command: raw,
1054
- validationErrors: ["command access failed"]
1055
- });
1056
- }
1057
- }
1058
- const projected = records.map((record) => view.get(record.id) ?? record);
693
+ const sources = agenticMemoryProjection(
694
+ graph,
695
+ projection,
696
+ `${name}/sources`,
697
+ "agenticMemorySources",
698
+ (fact) => Object.freeze(
699
+ fact.fragments.map(
700
+ (fragment) => Object.freeze({
701
+ fragmentId: fragment.id,
702
+ ...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
703
+ sources: Object.freeze([...fragment.sources]),
704
+ ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
705
+ ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
706
+ })
707
+ )
708
+ )
709
+ );
710
+ const context = agenticMemoryContextProjection(
711
+ graph,
712
+ projection,
713
+ retrieval.snapshot,
714
+ `${name}/context`
715
+ );
1059
716
  return {
1060
- activeRecords: projected.filter((record) => record.persistenceLevel !== "archived"),
1061
- archivedRecords: projected.filter((record) => record.persistenceLevel === "archived"),
1062
- consolidationRequests: requests,
717
+ input: { records: opts.records, query: opts.query },
718
+ projection,
719
+ retrieval,
720
+ retrievalSnapshot: retrieval.snapshot,
721
+ records: projectedRecords,
722
+ fragments: projectedFragments,
723
+ sources,
724
+ indexed: retrieval.indexed,
725
+ ranked: retrieval.ranked,
726
+ context,
727
+ status,
1063
728
  errors,
1064
- validCommands,
1065
- invalidCommands
729
+ retrievalStatus: retrieval.status,
730
+ retrievalErrors: retrieval.errors,
731
+ cursor: retrieval.cursor
1066
732
  };
1067
733
  }
1068
- function validateRetentionCommand(value, index) {
1069
- if (!isPlainRecord(value)) {
1070
- return {
1071
- errors: [
1072
- {
1073
- code: "invalid-command",
1074
- message: "agenticMemoryRetentionBundle: command must be an object",
1075
- index,
1076
- command: value
1077
- }
1078
- ]
1079
- };
1080
- }
1081
- const id = typeof value.id === "string" && value.id.length > 0 ? value.id : void 0;
1082
- const kind = value.kind;
1083
- const errors = [];
1084
- if (id === void 0) errors.push("command.id must be a non-empty string");
1085
- if (kind !== "archive" && kind !== "restore" && kind !== "setPersistenceLevel" && kind !== "requestConsolidation") {
1086
- errors.push("command.kind is invalid");
1087
- }
1088
- if (value.reason !== void 0 && typeof value.reason !== "string") {
1089
- errors.push("command.reason must be a string when present");
1090
- }
1091
- if (kind === "archive") {
1092
- if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
1093
- } else if (kind === "restore") {
1094
- if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
1095
- if (value.persistenceLevel !== void 0 && (!isAgenticMemoryPersistenceLevel(value.persistenceLevel) || value.persistenceLevel === "archived")) {
1096
- errors.push("restore.persistenceLevel must be a non-archived persistence level when present");
1097
- }
1098
- } else if (kind === "setPersistenceLevel") {
1099
- if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
1100
- if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
1101
- errors.push("setPersistenceLevel.persistenceLevel is invalid");
1102
- }
1103
- } else if (kind === "requestConsolidation") {
1104
- if (!isDenseArrayOf(value.recordIds, isNonEmptyString) || value.recordIds.length === 0) {
1105
- errors.push("requestConsolidation.recordIds must be a non-empty string array");
1106
- }
1107
- if (value.requestId !== void 0 && (typeof value.requestId !== "string" || value.requestId.length === 0)) {
1108
- errors.push("requestConsolidation.requestId must be non-empty when present");
734
+
735
+ // src/solutions/agentic-memory-consolidation.ts
736
+ function agenticMemoryConsolidationBundle(graph, opts) {
737
+ const name = opts.name ?? "agenticMemoryConsolidation";
738
+ const projection = graph.node(
739
+ [opts.records, opts.requests, opts.outcomes],
740
+ (ctx) => {
741
+ const state = ctx.state.get() ?? { evaluation: 0 };
742
+ state.evaluation += 1;
743
+ const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
744
+ const requests = validateConsolidationRequests(depLatest(ctx, 1), recordProjection.records);
745
+ const outcomes = projectConsolidationOutcomes(
746
+ depLatest(ctx, 2),
747
+ requests.requests,
748
+ state.evaluation
749
+ );
750
+ const cursor = Object.freeze({
751
+ evaluation: state.evaluation,
752
+ validRequests: requests.requests.length,
753
+ validOutcomes: outcomes.validOutcomes,
754
+ invalidOutcomes: outcomes.invalidOutcomes,
755
+ results: outcomes.results.length,
756
+ proposedRecordDrafts: outcomes.proposedRecordDrafts.length
757
+ });
758
+ const errors = Object.freeze(
759
+ [
760
+ ...recordProjection.errors.map(consolidationErrorFromRecordError),
761
+ ...requests.errors.map(consolidationErrorFromRetentionError),
762
+ ...outcomes.errors
763
+ ].map((error) => freezeError({ ...error, cursor }))
764
+ );
765
+ const status = Object.freeze({
766
+ state: agenticStatusState(errors.length, outcomes.results.length),
767
+ cursor
768
+ });
769
+ ctx.state.set(state);
770
+ ctx.down([
771
+ [
772
+ "DATA",
773
+ Object.freeze({
774
+ results: Object.freeze(outcomes.results),
775
+ proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
776
+ commands: Object.freeze(outcomes.commands),
777
+ status,
778
+ errors,
779
+ cursor
780
+ })
781
+ ]
782
+ ]);
783
+ },
784
+ {
785
+ name: `${name}/projection`,
786
+ factory: "agenticMemoryConsolidation",
787
+ completeWhenDepsComplete: false,
788
+ errorWhenDepsError: false
1109
789
  }
1110
- }
1111
- if (errors.length > 0 || id === void 0) {
1112
- return {
1113
- errors: [
1114
- {
1115
- code: "invalid-command",
1116
- message: "agenticMemoryRetentionBundle: command is invalid",
1117
- index,
1118
- commandId: id,
1119
- command: value,
1120
- validationErrors: Object.freeze(errors)
1121
- }
1122
- ]
1123
- };
1124
- }
1125
- const base = { id, reason: value.reason };
1126
- if (kind === "archive") {
1127
- return {
1128
- command: Object.freeze({
1129
- ...base,
1130
- kind,
1131
- recordId: value.recordId,
1132
- ...base.reason === void 0 ? {} : { reason: base.reason }
1133
- }),
1134
- errors: []
1135
- };
1136
- }
1137
- if (kind === "restore") {
1138
- return {
1139
- command: Object.freeze({
1140
- ...base,
1141
- kind,
1142
- recordId: value.recordId,
1143
- ...value.persistenceLevel === void 0 ? {} : {
1144
- persistenceLevel: value.persistenceLevel
1145
- },
1146
- ...base.reason === void 0 ? {} : { reason: base.reason }
1147
- }),
1148
- errors: []
1149
- };
1150
- }
1151
- if (kind === "setPersistenceLevel") {
1152
- return {
1153
- command: Object.freeze({
1154
- ...base,
1155
- kind,
1156
- recordId: value.recordId,
1157
- persistenceLevel: value.persistenceLevel,
1158
- ...base.reason === void 0 ? {} : { reason: base.reason }
1159
- }),
1160
- errors: []
1161
- };
1162
- }
1163
- return {
1164
- command: Object.freeze({
1165
- ...base,
1166
- kind: "requestConsolidation",
1167
- recordIds: Object.freeze([...value.recordIds]),
1168
- ...value.requestId === void 0 ? {} : { requestId: value.requestId },
1169
- ...base.reason === void 0 ? {} : { reason: base.reason }
1170
- }),
1171
- errors: []
1172
- };
1173
- }
1174
- function retentionMissingRecords(command, records) {
1175
- if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
1176
- return command.recordIds.filter((recordId) => !records.has(recordId));
1177
- }
1178
- function applyRetentionCommand(command, source, view, requests) {
1179
- if (command.kind === "requestConsolidation") {
1180
- requests.push(
1181
- Object.freeze({
1182
- id: command.requestId ?? command.id,
1183
- commandId: command.id,
1184
- recordIds: Object.freeze([...command.recordIds]),
1185
- ...command.reason === void 0 ? {} : { reason: command.reason }
1186
- })
1187
- );
1188
- return;
1189
- }
1190
- const record = view.get(command.recordId) ?? source.get(command.recordId);
1191
- if (record === void 0) return;
1192
- const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
1193
- view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
1194
- }
1195
- function nonArchivedLevel(record) {
1196
- return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
1197
- }
1198
- function withPersistenceLevel(record, persistenceLevel) {
1199
- return Object.freeze({
1200
- ...record,
1201
- persistenceLevel
1202
- });
1203
- }
1204
- function retentionErrorFromRecordError(error) {
790
+ );
1205
791
  return {
1206
- ...error,
1207
- code: error.code
792
+ input: { records: opts.records, requests: opts.requests, outcomes: opts.outcomes },
793
+ projection,
794
+ results: solutionProjection(
795
+ graph,
796
+ projection,
797
+ `${name}/results`,
798
+ "agenticMemoryConsolidationResults",
799
+ (fact) => fact.results
800
+ ),
801
+ proposedRecordDrafts: solutionProjection(
802
+ graph,
803
+ projection,
804
+ `${name}/proposedRecordDrafts`,
805
+ "agenticMemoryConsolidationRecordDrafts",
806
+ (fact) => fact.proposedRecordDrafts
807
+ ),
808
+ commands: solutionProjection(
809
+ graph,
810
+ projection,
811
+ `${name}/commands`,
812
+ "agenticMemoryConsolidationCommands",
813
+ (fact) => fact.commands
814
+ ),
815
+ status: solutionProjection(
816
+ graph,
817
+ projection,
818
+ `${name}/status`,
819
+ "agenticMemoryConsolidationStatus",
820
+ (fact) => fact.status
821
+ ),
822
+ errors: solutionProjection(
823
+ graph,
824
+ projection,
825
+ `${name}/errors`,
826
+ "agenticMemoryConsolidationErrors",
827
+ (fact) => fact.errors
828
+ ),
829
+ cursor: solutionProjection(
830
+ graph,
831
+ projection,
832
+ `${name}/cursor`,
833
+ "agenticMemoryConsolidationCursor",
834
+ (fact) => fact.cursor
835
+ )
1208
836
  };
1209
837
  }
1210
838
  function validateConsolidationRequests(value, records) {
@@ -1590,6 +1218,64 @@ function consolidationErrorFromRetentionError(error) {
1590
1218
  code: error.code
1591
1219
  };
1592
1220
  }
1221
+
1222
+ // src/solutions/agentic-memory-context-packing.ts
1223
+ function agenticMemoryContextPackingBundle(graph, opts) {
1224
+ const name = opts.name ?? "agenticMemoryContextPacking";
1225
+ const projection = graph.node(
1226
+ [opts.context, opts.texts, opts.policy],
1227
+ (ctx) => {
1228
+ const state = ctx.state.get() ?? { evaluation: 0 };
1229
+ state.evaluation += 1;
1230
+ const packed = packContext(
1231
+ depLatest(ctx, 0),
1232
+ depLatest(ctx, 1),
1233
+ depLatest(ctx, 2),
1234
+ state.evaluation
1235
+ );
1236
+ ctx.state.set(state);
1237
+ ctx.down([["DATA", packed]]);
1238
+ },
1239
+ {
1240
+ name: `${name}/projection`,
1241
+ factory: "agenticMemoryContextPacking",
1242
+ completeWhenDepsComplete: false,
1243
+ errorWhenDepsError: false
1244
+ }
1245
+ );
1246
+ return {
1247
+ input: { context: opts.context, texts: opts.texts, policy: opts.policy },
1248
+ projection,
1249
+ packedContext: solutionProjection(
1250
+ graph,
1251
+ projection,
1252
+ `${name}/packedContext`,
1253
+ "agenticMemoryPackedContext",
1254
+ (fact) => fact.packedContext
1255
+ ),
1256
+ status: solutionProjection(
1257
+ graph,
1258
+ projection,
1259
+ `${name}/status`,
1260
+ "agenticMemoryContextPackingStatus",
1261
+ (fact) => fact.status
1262
+ ),
1263
+ errors: solutionProjection(
1264
+ graph,
1265
+ projection,
1266
+ `${name}/errors`,
1267
+ "agenticMemoryContextPackingErrors",
1268
+ (fact) => fact.errors
1269
+ ),
1270
+ cursor: solutionProjection(
1271
+ graph,
1272
+ projection,
1273
+ `${name}/cursor`,
1274
+ "agenticMemoryContextPackingCursor",
1275
+ (fact) => fact.cursor
1276
+ )
1277
+ };
1278
+ }
1593
1279
  function packContext(contextValue, textsValue, policyValue, evaluation) {
1594
1280
  const errors = [];
1595
1281
  const context = validatePackingContext(contextValue, errors);
@@ -1669,781 +1355,1655 @@ function packContext(contextValue, textsValue, policyValue, evaluation) {
1669
1355
  cursor
1670
1356
  });
1671
1357
  }
1672
- function validatePackingContext(value, errors) {
1358
+ function validatePackingContext(value, errors) {
1359
+ if (!isPlainRecord(value)) {
1360
+ errors.push({
1361
+ code: "invalid-context",
1362
+ message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
1363
+ value
1364
+ });
1365
+ return void 0;
1366
+ }
1367
+ let entriesValue;
1368
+ try {
1369
+ entriesValue = value.entries;
1370
+ } catch (error) {
1371
+ errors.push({
1372
+ code: "invalid-context",
1373
+ message: `agenticMemoryContextPackingBundle: context entries access failed: ${errorMessage(error)}`,
1374
+ value,
1375
+ validationErrors: ["context entries access failed"]
1376
+ });
1377
+ return void 0;
1378
+ }
1379
+ if (!Array.isArray(entriesValue)) {
1380
+ errors.push({
1381
+ code: "invalid-context",
1382
+ message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
1383
+ value,
1384
+ validationErrors: ["context.entries must be an array"]
1385
+ });
1386
+ return void 0;
1387
+ }
1388
+ const length = safeArrayLength(entriesValue);
1389
+ if (length === void 0) {
1390
+ errors.push({
1391
+ code: "invalid-context",
1392
+ message: "agenticMemoryContextPackingBundle: context entries length could not be read",
1393
+ value,
1394
+ validationErrors: ["context.entries length could not be read"]
1395
+ });
1396
+ return void 0;
1397
+ }
1398
+ const entries = [];
1399
+ for (let i = 0; i < length; i += 1) {
1400
+ let raw;
1401
+ try {
1402
+ raw = entriesValue[i];
1403
+ if (!isPlainRecord(raw) || !isNonEmptyString(raw.fragmentId)) {
1404
+ errors.push({
1405
+ code: "invalid-context",
1406
+ message: "agenticMemoryContextPackingBundle: context entry is invalid",
1407
+ index: i,
1408
+ value: raw,
1409
+ validationErrors: ["context entry fragmentId must be a non-empty string"]
1410
+ });
1411
+ continue;
1412
+ }
1413
+ const record = validateRecordMetadata(raw.record);
1414
+ if (!record.ok) {
1415
+ errors.push({
1416
+ code: "invalid-context",
1417
+ message: "agenticMemoryContextPackingBundle: context entry record metadata is invalid",
1418
+ index: i,
1419
+ fragmentId: raw.fragmentId,
1420
+ value: raw,
1421
+ validationErrors: Object.freeze(record.errors)
1422
+ });
1423
+ continue;
1424
+ }
1425
+ entries.push(
1426
+ Object.freeze({
1427
+ fragmentId: raw.fragmentId,
1428
+ ...record.metadata === void 0 ? {} : { record: record.metadata }
1429
+ })
1430
+ );
1431
+ } catch (error) {
1432
+ errors.push({
1433
+ code: "invalid-context",
1434
+ message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage(error)}`,
1435
+ index: i,
1436
+ value: raw,
1437
+ validationErrors: ["context entry access failed"]
1438
+ });
1439
+ }
1440
+ }
1441
+ return Object.freeze({
1442
+ entries: Object.freeze(entries)
1443
+ });
1444
+ }
1445
+ function validateContextTexts(value, errors) {
1446
+ const out = /* @__PURE__ */ new Map();
1447
+ if (!Array.isArray(value)) {
1448
+ errors.push({
1449
+ code: "invalid-texts-input",
1450
+ message: "agenticMemoryContextPackingBundle: texts input must be an array",
1451
+ value
1452
+ });
1453
+ return out;
1454
+ }
1455
+ const length = safeArrayLength(value);
1456
+ if (length === void 0) {
1457
+ errors.push({
1458
+ code: "invalid-texts-input",
1459
+ message: "agenticMemoryContextPackingBundle: texts input length could not be read",
1460
+ value
1461
+ });
1462
+ return out;
1463
+ }
1464
+ for (let i = 0; i < length; i += 1) {
1465
+ try {
1466
+ const raw = value[i];
1467
+ const result = validateContextText(raw, i);
1468
+ if (result.error !== void 0) {
1469
+ errors.push(result.error);
1470
+ continue;
1471
+ }
1472
+ if (result.text === void 0) {
1473
+ errors.push({
1474
+ code: "invalid-text",
1475
+ message: "agenticMemoryContextPackingBundle: text fact is invalid",
1476
+ index: i,
1477
+ value: raw,
1478
+ validationErrors: ["text validation returned no fact"]
1479
+ });
1480
+ continue;
1481
+ }
1482
+ if (out.has(result.text.fragmentId)) {
1483
+ errors.push({
1484
+ code: "duplicate-text-fragment-id",
1485
+ message: "agenticMemoryContextPackingBundle: duplicate text fragment id",
1486
+ index: i,
1487
+ fragmentId: result.text.fragmentId,
1488
+ value: raw,
1489
+ validationErrors: [`duplicate text fragment id '${result.text.fragmentId}'`]
1490
+ });
1491
+ continue;
1492
+ }
1493
+ out.set(result.text.fragmentId, result.text);
1494
+ } catch (error) {
1495
+ errors.push({
1496
+ code: "invalid-text",
1497
+ message: `agenticMemoryContextPackingBundle: text access failed: ${errorMessage(error)}`,
1498
+ index: i,
1499
+ validationErrors: ["text access failed"]
1500
+ });
1501
+ }
1502
+ }
1503
+ return out;
1504
+ }
1505
+ function validateContextText(value, index) {
1506
+ if (!isPlainRecord(value)) {
1507
+ return {
1508
+ error: {
1509
+ code: "invalid-text",
1510
+ message: "agenticMemoryContextPackingBundle: text fact must be an object",
1511
+ index,
1512
+ value
1513
+ }
1514
+ };
1515
+ }
1516
+ const errors = [];
1517
+ if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
1518
+ if (typeof value.text !== "string") errors.push("text must be a string");
1519
+ if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
1520
+ errors.push("cost must be a finite number >= 0");
1521
+ }
1522
+ if (value.metadata !== void 0) {
1523
+ try {
1524
+ if (!isPlainRecord(value.metadata)) {
1525
+ throw new TypeError("metadata must be a plain object when present");
1526
+ }
1527
+ assertStrictJsonValue(value.metadata, "metadata");
1528
+ } catch (error) {
1529
+ errors.push(errorMessage(error));
1530
+ }
1531
+ }
1532
+ if (errors.length > 0) {
1533
+ return {
1534
+ error: {
1535
+ code: "invalid-text",
1536
+ message: "agenticMemoryContextPackingBundle: text fact is invalid",
1537
+ index,
1538
+ fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
1539
+ value,
1540
+ validationErrors: Object.freeze(errors)
1541
+ }
1542
+ };
1543
+ }
1544
+ return {
1545
+ text: Object.freeze({
1546
+ fragmentId: value.fragmentId,
1547
+ text: value.text,
1548
+ ...value.cost === void 0 ? {} : { cost: value.cost },
1549
+ ...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
1550
+ })
1551
+ };
1552
+ }
1553
+ function validatePackingPolicy(value, errors) {
1673
1554
  if (!isPlainRecord(value)) {
1674
1555
  errors.push({
1675
- code: "invalid-context",
1676
- message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
1556
+ code: "invalid-policy",
1557
+ message: "agenticMemoryContextPackingBundle: policy must be an object",
1677
1558
  value
1678
1559
  });
1679
1560
  return void 0;
1680
1561
  }
1681
- let entriesValue;
1562
+ const validation = [];
1563
+ let maxEntries;
1564
+ let maxChars;
1565
+ let maxCost;
1566
+ let includeMetadata;
1682
1567
  try {
1683
- entriesValue = value.entries;
1568
+ maxEntries = value.maxEntries;
1569
+ maxChars = value.maxChars;
1570
+ maxCost = value.maxCost;
1571
+ includeMetadata = value.includeMetadata;
1684
1572
  } catch (error) {
1685
1573
  errors.push({
1686
- code: "invalid-context",
1687
- message: `agenticMemoryContextPackingBundle: context entries access failed: ${errorMessage(error)}`,
1574
+ code: "invalid-policy",
1575
+ message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage(error)}`,
1688
1576
  value,
1689
- validationErrors: ["context entries access failed"]
1577
+ validationErrors: ["policy access failed"]
1690
1578
  });
1691
1579
  return void 0;
1692
1580
  }
1693
- if (!Array.isArray(entriesValue)) {
1581
+ if (maxEntries !== void 0 && (typeof maxEntries !== "number" || !Number.isSafeInteger(maxEntries) || maxEntries < 0)) {
1582
+ validation.push("maxEntries must be a safe integer >= 0");
1583
+ }
1584
+ if (maxChars !== void 0 && (typeof maxChars !== "number" || !Number.isSafeInteger(maxChars) || maxChars < 0)) {
1585
+ validation.push("maxChars must be a safe integer >= 0");
1586
+ }
1587
+ if (maxCost !== void 0 && (typeof maxCost !== "number" || !Number.isFinite(maxCost) || maxCost < 0)) {
1588
+ validation.push("maxCost must be a finite number >= 0");
1589
+ }
1590
+ if (includeMetadata !== void 0 && typeof includeMetadata !== "boolean") {
1591
+ validation.push("includeMetadata must be a boolean when present");
1592
+ }
1593
+ if (validation.length > 0) {
1694
1594
  errors.push({
1695
- code: "invalid-context",
1696
- message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
1595
+ code: "invalid-policy",
1596
+ message: "agenticMemoryContextPackingBundle: policy is invalid",
1697
1597
  value,
1698
- validationErrors: ["context.entries must be an array"]
1598
+ validationErrors: Object.freeze(validation)
1699
1599
  });
1700
1600
  return void 0;
1701
1601
  }
1702
- const length = safeArrayLength(entriesValue);
1602
+ return Object.freeze({
1603
+ ...maxEntries === void 0 ? {} : { maxEntries },
1604
+ ...maxChars === void 0 ? {} : { maxChars },
1605
+ ...maxCost === void 0 ? {} : { maxCost },
1606
+ ...includeMetadata === void 0 ? {} : { includeMetadata }
1607
+ });
1608
+ }
1609
+
1610
+ // src/solutions/agentic-memory-frame.ts
1611
+ var AGENTIC_MEMORY_RECORD_FRAME_FORMAT = "graphrefly.agenticMemoryRecord";
1612
+ var AGENTIC_MEMORY_RECORD_FRAME_VERSION = 1;
1613
+ function agenticMemoryRecordFrame(record) {
1614
+ const result = validateAndSnapshotRecord(record, 0);
1615
+ if (result.errors.length > 0 || result.record === void 0) {
1616
+ throw new TypeError(
1617
+ `agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
1618
+ );
1619
+ }
1620
+ assertAgenticMemoryRecordCodecShape(record);
1621
+ assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
1622
+ return Object.freeze({
1623
+ format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
1624
+ version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
1625
+ record: Object.freeze({
1626
+ id: result.record.id,
1627
+ kind: result.record.kind,
1628
+ persistenceLevel: result.record.persistenceLevel,
1629
+ artifactKind: result.record.artifactKind,
1630
+ ...result.record.scope === void 0 ? {} : { scope: result.record.scope },
1631
+ fragment: fragmentFrame(result.record.fragment)
1632
+ })
1633
+ });
1634
+ }
1635
+ function assertAgenticMemoryRecordFrame(value) {
1636
+ if (!isPlainRecord(value))
1637
+ throw new TypeError("agenticMemoryRecordFrame: frame must be an object");
1638
+ assertStrictJsonValue(value, "agenticMemoryRecordFrame");
1639
+ assertExactKeys(value, ["format", "record", "version"], "agenticMemoryRecordFrame");
1640
+ if (value.format !== AGENTIC_MEMORY_RECORD_FRAME_FORMAT) {
1641
+ throw new TypeError("agenticMemoryRecordFrame: invalid format");
1642
+ }
1643
+ if (value.version !== AGENTIC_MEMORY_RECORD_FRAME_VERSION) {
1644
+ throw new TypeError("agenticMemoryRecordFrame: invalid version");
1645
+ }
1646
+ const rawRecord = value.record;
1647
+ if (!isPlainRecord(rawRecord)) {
1648
+ throw new TypeError("agenticMemoryRecordFrame: record must be an object");
1649
+ }
1650
+ assertExactKeys(
1651
+ rawRecord,
1652
+ rawRecord.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
1653
+ "agenticMemoryRecordFrame.record"
1654
+ );
1655
+ const rawFragment = rawRecord.fragment;
1656
+ if (!isPlainRecord(rawFragment)) {
1657
+ throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
1658
+ }
1659
+ assertExactKeys(
1660
+ rawFragment,
1661
+ [
1662
+ "id",
1663
+ "payload",
1664
+ "tNs",
1665
+ ...rawFragment.validFrom === void 0 ? [] : ["validFrom"],
1666
+ ...rawFragment.validTo === void 0 ? [] : ["validTo"],
1667
+ "confidence",
1668
+ "tags",
1669
+ "sources",
1670
+ ...rawFragment.embedding === void 0 ? [] : ["embedding"],
1671
+ ...rawFragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
1672
+ ...rawFragment.provenance === void 0 ? [] : ["provenance"]
1673
+ ],
1674
+ "agenticMemoryRecordFrame.record.fragment"
1675
+ );
1676
+ if (rawRecord.scope !== void 0) assertScopeFrame(rawRecord.scope);
1677
+ const frame = value;
1678
+ const decoded = recordFromFrame(frame);
1679
+ const roundtrip = agenticMemoryRecordFrame(decoded);
1680
+ return roundtrip;
1681
+ }
1682
+ function agenticMemoryRecordFrameCodec() {
1683
+ return {
1684
+ encode(value) {
1685
+ return strictJsonCodec.encode(assertAgenticMemoryRecordFrame(value));
1686
+ },
1687
+ decode(bytes) {
1688
+ return assertAgenticMemoryRecordFrame(strictJsonCodec.decode(bytes));
1689
+ }
1690
+ };
1691
+ }
1692
+ function agenticMemoryRecordCodec() {
1693
+ const frameCodec = agenticMemoryRecordFrameCodec();
1694
+ return {
1695
+ encode(value) {
1696
+ return frameCodec.encode(agenticMemoryRecordFrame(value));
1697
+ },
1698
+ decode(bytes) {
1699
+ return recordFromFrame(frameCodec.decode(bytes));
1700
+ }
1701
+ };
1702
+ }
1703
+ function fragmentFrame(fragment) {
1704
+ return Object.freeze({
1705
+ id: fragment.id,
1706
+ payload: fragment.payload,
1707
+ tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
1708
+ ...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
1709
+ ...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
1710
+ confidence: fragment.confidence,
1711
+ tags: Object.freeze([...fragment.tags]),
1712
+ sources: Object.freeze([...fragment.sources]),
1713
+ ...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
1714
+ ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
1715
+ ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
1716
+ });
1717
+ }
1718
+ function recordFromFrame(frame) {
1719
+ const fragment = frame.record.fragment;
1720
+ const record = {
1721
+ id: assertNonEmptyString(frame.record.id, "record.id"),
1722
+ kind: assertKindValue(frame.record.kind),
1723
+ persistenceLevel: assertPersistenceLevelValue(frame.record.persistenceLevel),
1724
+ artifactKind: assertArtifactKindValue(frame.record.artifactKind),
1725
+ ...frame.record.scope === void 0 ? {} : { scope: assertScopeFrame(frame.record.scope) },
1726
+ fragment: {
1727
+ id: assertNonEmptyString(fragment.id, "fragment.id"),
1728
+ payload: assertStrictJsonValue(fragment.payload, "fragment.payload"),
1729
+ tNs: parseDecimalBigInt(fragment.tNs, "fragment.tNs"),
1730
+ ...fragment.validFrom === void 0 ? {} : { validFrom: parseDecimalBigInt(fragment.validFrom, "fragment.validFrom") },
1731
+ ...fragment.validTo === void 0 ? {} : { validTo: parseDecimalBigInt(fragment.validTo, "fragment.validTo") },
1732
+ confidence: assertConfidence(fragment.confidence, "fragment.confidence"),
1733
+ tags: assertStringArray(fragment.tags, "fragment.tags"),
1734
+ sources: assertStringArray(fragment.sources, "fragment.sources"),
1735
+ ...fragment.embedding === void 0 ? {} : { embedding: assertFiniteNumberArray(fragment.embedding, "fragment.embedding") },
1736
+ ...fragment.parentFragmentId === void 0 ? {} : {
1737
+ parentFragmentId: assertNonEmptyString(fragment.parentFragmentId, "parentFragmentId")
1738
+ },
1739
+ ...fragment.provenance === void 0 ? {} : { provenance: assertString(fragment.provenance, "provenance") }
1740
+ }
1741
+ };
1742
+ const result = validateAndSnapshotRecord(record, 0);
1743
+ if (result.errors.length > 0 || result.record === void 0) {
1744
+ throw new TypeError(
1745
+ `agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
1746
+ );
1747
+ }
1748
+ return result.record;
1749
+ }
1750
+
1751
+ // src/solutions/agentic-memory-kg.ts
1752
+ function agenticMemoryKgProjectionBundle(graph, opts) {
1753
+ const name = opts.name ?? "agenticMemoryKgProjection";
1754
+ const projection = graph.node(
1755
+ [opts.records, opts.drafts],
1756
+ (ctx) => {
1757
+ const state = ctx.state.get() ?? { evaluation: 0 };
1758
+ state.evaluation += 1;
1759
+ const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
1760
+ const draftProjection = validateAndProjectKgDrafts(
1761
+ depLatest(ctx, 1),
1762
+ recordProjection.records
1763
+ );
1764
+ const cursor = Object.freeze({
1765
+ evaluation: state.evaluation,
1766
+ validRecords: recordProjection.records.length,
1767
+ validDrafts: draftProjection.assertions.length,
1768
+ invalidDrafts: draftProjection.invalidDrafts,
1769
+ projectedAssertions: draftProjection.assertions.length
1770
+ });
1771
+ const errors = Object.freeze(
1772
+ [...recordProjection.errors.map(kgErrorFromRecordError), ...draftProjection.errors].map(
1773
+ (error) => freezeError({ ...error, cursor })
1774
+ )
1775
+ );
1776
+ const status = Object.freeze({
1777
+ state: agenticStatusState(errors.length, draftProjection.assertions.length),
1778
+ cursor
1779
+ });
1780
+ ctx.state.set(state);
1781
+ ctx.down([
1782
+ [
1783
+ "DATA",
1784
+ Object.freeze({
1785
+ assertions: Object.freeze(draftProjection.assertions),
1786
+ status,
1787
+ errors,
1788
+ cursor
1789
+ })
1790
+ ]
1791
+ ]);
1792
+ },
1793
+ {
1794
+ name: `${name}/projection`,
1795
+ factory: "agenticMemoryKgProjection",
1796
+ completeWhenDepsComplete: false,
1797
+ errorWhenDepsError: false
1798
+ }
1799
+ );
1800
+ return {
1801
+ input: { records: opts.records, drafts: opts.drafts },
1802
+ projection,
1803
+ assertions: solutionProjection(
1804
+ graph,
1805
+ projection,
1806
+ `${name}/assertions`,
1807
+ "agenticMemoryKgAssertions",
1808
+ (fact) => fact.assertions
1809
+ ),
1810
+ status: solutionProjection(
1811
+ graph,
1812
+ projection,
1813
+ `${name}/status`,
1814
+ "agenticMemoryKgStatus",
1815
+ (fact) => fact.status
1816
+ ),
1817
+ errors: solutionProjection(
1818
+ graph,
1819
+ projection,
1820
+ `${name}/errors`,
1821
+ "agenticMemoryKgErrors",
1822
+ (fact) => fact.errors
1823
+ ),
1824
+ cursor: solutionProjection(
1825
+ graph,
1826
+ projection,
1827
+ `${name}/cursor`,
1828
+ "agenticMemoryKgCursor",
1829
+ (fact) => fact.cursor
1830
+ )
1831
+ };
1832
+ }
1833
+ function validateAndProjectKgDrafts(value, records) {
1834
+ const assertions = [];
1835
+ const errors = [];
1836
+ let invalidDrafts = 0;
1837
+ if (!Array.isArray(value)) {
1838
+ return {
1839
+ assertions,
1840
+ invalidDrafts: 1,
1841
+ errors: [
1842
+ {
1843
+ code: "invalid-drafts-input",
1844
+ message: "agenticMemoryKgProjectionBundle: drafts input must be an array",
1845
+ draft: value
1846
+ }
1847
+ ]
1848
+ };
1849
+ }
1850
+ const length = safeArrayLength(value);
1703
1851
  if (length === void 0) {
1704
- errors.push({
1705
- code: "invalid-context",
1706
- message: "agenticMemoryContextPackingBundle: context entries length could not be read",
1707
- value,
1708
- validationErrors: ["context.entries length could not be read"]
1709
- });
1710
- return void 0;
1852
+ return {
1853
+ assertions,
1854
+ invalidDrafts: 1,
1855
+ errors: [
1856
+ {
1857
+ code: "invalid-drafts-input",
1858
+ message: "agenticMemoryKgProjectionBundle: drafts input length could not be read",
1859
+ draft: value
1860
+ }
1861
+ ]
1862
+ };
1711
1863
  }
1712
- const entries = [];
1864
+ const recordById = new Map(records.map((record) => [record.id, record]));
1865
+ const fragmentToRecord = new Map(records.map((record) => [record.fragment.id, record.id]));
1866
+ const seenAssertions = /* @__PURE__ */ new Set();
1713
1867
  for (let i = 0; i < length; i += 1) {
1714
1868
  let raw;
1715
1869
  try {
1716
- raw = entriesValue[i];
1717
- if (!isPlainRecord(raw) || !isNonEmptyString(raw.fragmentId)) {
1870
+ raw = value[i];
1871
+ const result = validateKgDraft(raw, i);
1872
+ if (result.errors.length > 0 || result.draft === void 0) {
1873
+ invalidDrafts += 1;
1874
+ errors.push(...result.errors);
1875
+ continue;
1876
+ }
1877
+ const draft = result.draft;
1878
+ if (seenAssertions.has(draft.id)) {
1879
+ invalidDrafts += 1;
1718
1880
  errors.push({
1719
- code: "invalid-context",
1720
- message: "agenticMemoryContextPackingBundle: context entry is invalid",
1881
+ code: "duplicate-assertion-id",
1882
+ message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
1721
1883
  index: i,
1722
- value: raw,
1723
- validationErrors: ["context entry fragmentId must be a non-empty string"]
1884
+ assertionId: draft.id,
1885
+ recordId: draft.recordId,
1886
+ fragmentId: draft.fragmentId,
1887
+ draft: raw,
1888
+ validationErrors: [`duplicate assertion id '${draft.id}'`]
1724
1889
  });
1725
1890
  continue;
1726
1891
  }
1727
- const record = validateRecordMetadata(raw.record);
1728
- if (!record.ok) {
1892
+ const record = recordById.get(draft.recordId);
1893
+ if (record === void 0) {
1894
+ invalidDrafts += 1;
1729
1895
  errors.push({
1730
- code: "invalid-context",
1731
- message: "agenticMemoryContextPackingBundle: context entry record metadata is invalid",
1896
+ code: "missing-record-ref",
1897
+ message: "agenticMemoryKgProjectionBundle: draft references a missing record",
1732
1898
  index: i,
1733
- fragmentId: raw.fragmentId,
1734
- value: raw,
1735
- validationErrors: Object.freeze(record.errors)
1899
+ assertionId: draft.id,
1900
+ recordId: draft.recordId,
1901
+ fragmentId: draft.fragmentId,
1902
+ draft: raw,
1903
+ validationErrors: [`record '${draft.recordId}' is not projected`]
1736
1904
  });
1737
1905
  continue;
1738
1906
  }
1739
- entries.push(
1740
- Object.freeze({
1741
- fragmentId: raw.fragmentId,
1742
- ...record.metadata === void 0 ? {} : { record: record.metadata }
1743
- })
1744
- );
1745
- } catch (error) {
1746
- errors.push({
1747
- code: "invalid-context",
1748
- message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage(error)}`,
1749
- index: i,
1750
- value: raw,
1751
- validationErrors: ["context entry access failed"]
1752
- });
1753
- }
1754
- }
1755
- return Object.freeze({
1756
- entries: Object.freeze(entries)
1757
- });
1758
- }
1759
- function validateContextTexts(value, errors) {
1760
- const out = /* @__PURE__ */ new Map();
1761
- if (!Array.isArray(value)) {
1762
- errors.push({
1763
- code: "invalid-texts-input",
1764
- message: "agenticMemoryContextPackingBundle: texts input must be an array",
1765
- value
1766
- });
1767
- return out;
1768
- }
1769
- const length = safeArrayLength(value);
1770
- if (length === void 0) {
1771
- errors.push({
1772
- code: "invalid-texts-input",
1773
- message: "agenticMemoryContextPackingBundle: texts input length could not be read",
1774
- value
1775
- });
1776
- return out;
1777
- }
1778
- for (let i = 0; i < length; i += 1) {
1779
- try {
1780
- const raw = value[i];
1781
- const result = validateContextText(raw, i);
1782
- if (result.error !== void 0) {
1783
- errors.push(result.error);
1784
- continue;
1785
- }
1786
- if (result.text === void 0) {
1907
+ const owner = fragmentToRecord.get(draft.fragmentId);
1908
+ if (owner === void 0) {
1909
+ invalidDrafts += 1;
1787
1910
  errors.push({
1788
- code: "invalid-text",
1789
- message: "agenticMemoryContextPackingBundle: text fact is invalid",
1911
+ code: "missing-fragment-ref",
1912
+ message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
1790
1913
  index: i,
1791
- value: raw,
1792
- validationErrors: ["text validation returned no fact"]
1914
+ assertionId: draft.id,
1915
+ recordId: draft.recordId,
1916
+ fragmentId: draft.fragmentId,
1917
+ draft: raw,
1918
+ validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
1793
1919
  });
1794
1920
  continue;
1795
1921
  }
1796
- if (out.has(result.text.fragmentId)) {
1922
+ if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
1923
+ invalidDrafts += 1;
1797
1924
  errors.push({
1798
- code: "duplicate-text-fragment-id",
1799
- message: "agenticMemoryContextPackingBundle: duplicate text fragment id",
1925
+ code: "fragment-record-mismatch",
1926
+ message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
1800
1927
  index: i,
1801
- fragmentId: result.text.fragmentId,
1802
- value: raw,
1803
- validationErrors: [`duplicate text fragment id '${result.text.fragmentId}'`]
1928
+ assertionId: draft.id,
1929
+ recordId: draft.recordId,
1930
+ fragmentId: draft.fragmentId,
1931
+ draft: raw,
1932
+ validationErrors: [
1933
+ `fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
1934
+ ]
1804
1935
  });
1805
1936
  continue;
1806
1937
  }
1807
- out.set(result.text.fragmentId, result.text);
1938
+ seenAssertions.add(draft.id);
1939
+ assertions.push(
1940
+ Object.freeze({
1941
+ id: draft.id,
1942
+ recordId: draft.recordId,
1943
+ fragmentId: draft.fragmentId,
1944
+ subject: draft.subject,
1945
+ predicate: draft.predicate,
1946
+ object: draft.object,
1947
+ ...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
1948
+ sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
1949
+ ...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
1950
+ })
1951
+ );
1808
1952
  } catch (error) {
1953
+ invalidDrafts += 1;
1809
1954
  errors.push({
1810
- code: "invalid-text",
1811
- message: `agenticMemoryContextPackingBundle: text access failed: ${errorMessage(error)}`,
1955
+ code: "invalid-draft",
1956
+ message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage(error)}`,
1812
1957
  index: i,
1813
- validationErrors: ["text access failed"]
1958
+ draft: raw,
1959
+ validationErrors: ["draft access failed"]
1814
1960
  });
1815
1961
  }
1816
1962
  }
1817
- return out;
1818
- }
1819
- function validateContextText(value, index) {
1820
- if (!isPlainRecord(value)) {
1821
- return {
1822
- error: {
1823
- code: "invalid-text",
1824
- message: "agenticMemoryContextPackingBundle: text fact must be an object",
1825
- index,
1826
- value
1827
- }
1828
- };
1829
- }
1830
- const errors = [];
1831
- if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
1832
- if (typeof value.text !== "string") errors.push("text must be a string");
1833
- if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
1834
- errors.push("cost must be a finite number >= 0");
1835
- }
1836
- if (value.metadata !== void 0) {
1837
- try {
1838
- if (!isPlainRecord(value.metadata)) {
1839
- throw new TypeError("metadata must be a plain object when present");
1840
- }
1841
- assertStrictJsonValue(value.metadata, "metadata");
1842
- } catch (error) {
1843
- errors.push(errorMessage(error));
1844
- }
1845
- }
1846
- if (errors.length > 0) {
1847
- return {
1848
- error: {
1849
- code: "invalid-text",
1850
- message: "agenticMemoryContextPackingBundle: text fact is invalid",
1851
- index,
1852
- fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
1853
- value,
1854
- validationErrors: Object.freeze(errors)
1855
- }
1856
- };
1857
- }
1858
- return {
1859
- text: Object.freeze({
1860
- fragmentId: value.fragmentId,
1861
- text: value.text,
1862
- ...value.cost === void 0 ? {} : { cost: value.cost },
1863
- ...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
1864
- })
1865
- };
1963
+ return { assertions, errors, invalidDrafts };
1866
1964
  }
1867
- function validatePackingPolicy(value, errors) {
1965
+ function validateKgDraft(value, index) {
1966
+ const errors = [];
1868
1967
  if (!isPlainRecord(value)) {
1869
- errors.push({
1870
- code: "invalid-policy",
1871
- message: "agenticMemoryContextPackingBundle: policy must be an object",
1872
- value
1873
- });
1874
- return void 0;
1968
+ return {
1969
+ errors: [
1970
+ {
1971
+ code: "invalid-draft",
1972
+ message: "agenticMemoryKgProjectionBundle: draft must be an object",
1973
+ index,
1974
+ draft: value
1975
+ }
1976
+ ]
1977
+ };
1875
1978
  }
1876
- const validation = [];
1877
- let maxEntries;
1878
- let maxChars;
1879
- let maxCost;
1880
- let includeMetadata;
1881
- try {
1882
- maxEntries = value.maxEntries;
1883
- maxChars = value.maxChars;
1884
- maxCost = value.maxCost;
1885
- includeMetadata = value.includeMetadata;
1886
- } catch (error) {
1887
- errors.push({
1888
- code: "invalid-policy",
1889
- message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage(error)}`,
1890
- value,
1891
- validationErrors: ["policy access failed"]
1892
- });
1893
- return void 0;
1979
+ const raw = value;
1980
+ const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
1981
+ const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
1982
+ const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
1983
+ const subject = validateAssertionSubject(raw.subject);
1984
+ const object = validateAssertionObject(raw.object);
1985
+ const shapeErrors = [];
1986
+ if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
1987
+ if (recordId === void 0) {
1988
+ shapeErrors.push("draft.recordId must be a non-empty string");
1894
1989
  }
1895
- if (maxEntries !== void 0 && (typeof maxEntries !== "number" || !Number.isSafeInteger(maxEntries) || maxEntries < 0)) {
1896
- validation.push("maxEntries must be a safe integer >= 0");
1990
+ if (fragmentId === void 0) {
1991
+ shapeErrors.push("draft.fragmentId must be a non-empty string");
1897
1992
  }
1898
- if (maxChars !== void 0 && (typeof maxChars !== "number" || !Number.isSafeInteger(maxChars) || maxChars < 0)) {
1899
- validation.push("maxChars must be a safe integer >= 0");
1993
+ shapeErrors.push(...subject.errors);
1994
+ if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
1995
+ shapeErrors.push("draft.predicate must be a non-empty string");
1900
1996
  }
1901
- if (maxCost !== void 0 && (typeof maxCost !== "number" || !Number.isFinite(maxCost) || maxCost < 0)) {
1902
- validation.push("maxCost must be a finite number >= 0");
1997
+ shapeErrors.push(...object.errors);
1998
+ if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
1999
+ shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
1903
2000
  }
1904
- if (includeMetadata !== void 0 && typeof includeMetadata !== "boolean") {
1905
- validation.push("includeMetadata must be a boolean when present");
2001
+ if (raw.sources !== void 0 && !isDenseArrayOf(raw.sources, isNonEmptyString)) {
2002
+ shapeErrors.push("draft.sources must be a readonly string array");
1906
2003
  }
1907
- if (validation.length > 0) {
1908
- errors.push({
1909
- code: "invalid-policy",
1910
- message: "agenticMemoryContextPackingBundle: policy is invalid",
1911
- value,
1912
- validationErrors: Object.freeze(validation)
1913
- });
1914
- return void 0;
2004
+ if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
2005
+ shapeErrors.push("draft.provenance must be a string when present");
1915
2006
  }
1916
- return Object.freeze({
1917
- ...maxEntries === void 0 ? {} : { maxEntries },
1918
- ...maxChars === void 0 ? {} : { maxChars },
1919
- ...maxCost === void 0 ? {} : { maxCost },
1920
- ...includeMetadata === void 0 ? {} : { includeMetadata }
1921
- });
2007
+ if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
2008
+ if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
2009
+ return { errors };
2010
+ }
2011
+ return {
2012
+ draft: Object.freeze({
2013
+ id,
2014
+ recordId,
2015
+ fragmentId,
2016
+ subject: subject.subject,
2017
+ predicate: raw.predicate,
2018
+ object: object.object,
2019
+ ...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
2020
+ ...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
2021
+ ...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
2022
+ }),
2023
+ errors
2024
+ };
1922
2025
  }
1923
- function validateAndProjectRecords(value) {
1924
- const records = [];
1925
- const fragments = [];
1926
- const metadataByFragmentId = /* @__PURE__ */ Object.create(null);
2026
+ function validateAssertionSubject(value) {
2027
+ if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
2028
+ const id = value.id;
2029
+ const type = value.type;
1927
2030
  const errors = [];
1928
- const invalidRecordIndexes = /* @__PURE__ */ new Set();
1929
- const seenRecordIds = /* @__PURE__ */ new Set();
1930
- const seenFragmentIds = /* @__PURE__ */ new Set();
1931
- if (!Array.isArray(value)) {
1932
- errors.push({
1933
- code: "invalid-records-input",
1934
- message: "agenticMemoryBundle: records input must be an array",
1935
- record: value
1936
- });
1937
- return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
2031
+ if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
2032
+ if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
2033
+ errors.push("subject.type must be a non-empty string when present");
1938
2034
  }
1939
- const length = safeArrayLength(value);
1940
- if (length === void 0) {
1941
- errors.push({
1942
- code: "invalid-records-input",
1943
- message: "agenticMemoryBundle: records input length could not be read",
1944
- record: value
1945
- });
1946
- return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
2035
+ if (errors.length > 0) return { errors };
2036
+ return {
2037
+ subject: Object.freeze({
2038
+ id,
2039
+ ...type === void 0 ? {} : { type }
2040
+ }),
2041
+ errors
2042
+ };
2043
+ }
2044
+ function validateAssertionObject(value) {
2045
+ if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
2046
+ const kind = value.kind;
2047
+ const errors = [];
2048
+ if (kind === "entity") {
2049
+ if (typeof value.id !== "string" || value.id.length === 0) {
2050
+ errors.push("object.id must be non-empty for entity objects");
2051
+ }
2052
+ if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
2053
+ errors.push("object.type must be a non-empty string when present");
2054
+ }
2055
+ if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
2056
+ if (errors.length > 0) return { errors };
2057
+ return {
2058
+ object: Object.freeze({
2059
+ kind: "entity",
2060
+ id: value.id,
2061
+ ...value.type === void 0 ? {} : { type: value.type }
2062
+ }),
2063
+ errors
2064
+ };
1947
2065
  }
1948
- for (let i = 0; i < length; i += 1) {
1949
- let raw;
1950
- try {
1951
- raw = value[i];
1952
- } catch (error) {
1953
- invalidRecordIndexes.add(i);
1954
- errors.push({
1955
- code: "invalid-record",
1956
- message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
1957
- index: i,
1958
- validationErrors: Object.freeze(["record access failed"])
1959
- });
1960
- continue;
2066
+ if (kind === "value") {
2067
+ if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
2068
+ else {
2069
+ try {
2070
+ assertStrictJsonValue(value.value, "object.value");
2071
+ } catch (error) {
2072
+ errors.push(errorMessage(error));
2073
+ }
1961
2074
  }
1962
- const result = validateAndSnapshotRecord(raw, i);
1963
- if (result.errors.length > 0) {
1964
- invalidRecordIndexes.add(i);
1965
- errors.push(...result.errors);
1966
- continue;
2075
+ if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
2076
+ errors.push("object.valueType must be a non-empty string when present");
1967
2077
  }
1968
- if (result.record === void 0) continue;
1969
- if (seenRecordIds.has(result.record.id)) {
1970
- invalidRecordIndexes.add(i);
1971
- errors.push({
1972
- code: "duplicate-record-id",
1973
- message: "agenticMemoryBundle: duplicate record id",
1974
- index: i,
1975
- recordId: result.record.id,
1976
- record: raw,
1977
- validationErrors: [`duplicate record id '${result.record.id}'`]
2078
+ if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
2079
+ if (errors.length > 0) return { errors };
2080
+ return {
2081
+ object: Object.freeze({
2082
+ kind: "value",
2083
+ value: value.value,
2084
+ ...value.valueType === void 0 ? {} : { valueType: value.valueType }
2085
+ }),
2086
+ errors
2087
+ };
2088
+ }
2089
+ return { errors: ["object.kind must be entity or value"] };
2090
+ }
2091
+ function kgShapeError(index, draft, ...validationErrors) {
2092
+ return {
2093
+ code: "invalid-assertion-shape",
2094
+ message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
2095
+ index,
2096
+ draft,
2097
+ validationErrors: Object.freeze([...validationErrors])
2098
+ };
2099
+ }
2100
+ function kgErrorFromRecordError(error) {
2101
+ return {
2102
+ ...error,
2103
+ code: error.code
2104
+ };
2105
+ }
2106
+
2107
+ // src/solutions/agentic-memory-retention.ts
2108
+ function agenticMemoryRetentionBundle(graph, opts) {
2109
+ const name = opts.name ?? "agenticMemoryRetention";
2110
+ const projection = graph.node(
2111
+ [opts.records, opts.commands],
2112
+ (ctx) => {
2113
+ const state = ctx.state.get() ?? { evaluation: 0 };
2114
+ state.evaluation += 1;
2115
+ const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
2116
+ const retention = projectRetention(depLatest(ctx, 1), recordProjection.records);
2117
+ const cursor = Object.freeze({
2118
+ evaluation: state.evaluation,
2119
+ validRecords: recordProjection.records.length,
2120
+ validCommands: retention.validCommands,
2121
+ invalidCommands: retention.invalidCommands,
2122
+ activeRecords: retention.activeRecords.length,
2123
+ archivedRecords: retention.archivedRecords.length,
2124
+ consolidationRequests: retention.consolidationRequests.length
1978
2125
  });
1979
- continue;
1980
- }
1981
- if (seenFragmentIds.has(result.record.fragment.id)) {
1982
- invalidRecordIndexes.add(i);
1983
- errors.push({
1984
- code: "duplicate-fragment-id",
1985
- message: "agenticMemoryBundle: duplicate fragment id",
1986
- index: i,
1987
- recordId: result.record.id,
1988
- fragmentId: result.record.fragment.id,
1989
- record: raw,
1990
- validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
2126
+ const errors = Object.freeze(
2127
+ [...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
2128
+ (error) => freezeError({ ...error, cursor })
2129
+ )
2130
+ );
2131
+ const status = Object.freeze({
2132
+ state: agenticStatusState(errors.length, recordProjection.records.length),
2133
+ cursor
1991
2134
  });
1992
- continue;
2135
+ ctx.state.set(state);
2136
+ ctx.down([
2137
+ [
2138
+ "DATA",
2139
+ Object.freeze({
2140
+ activeRecords: Object.freeze(retention.activeRecords),
2141
+ archivedRecords: Object.freeze(retention.archivedRecords),
2142
+ consolidationRequests: Object.freeze(retention.consolidationRequests),
2143
+ status,
2144
+ errors,
2145
+ cursor
2146
+ })
2147
+ ]
2148
+ ]);
2149
+ },
2150
+ {
2151
+ name: `${name}/projection`,
2152
+ factory: "agenticMemoryRetention",
2153
+ completeWhenDepsComplete: false,
2154
+ errorWhenDepsError: false
1993
2155
  }
1994
- seenRecordIds.add(result.record.id);
1995
- seenFragmentIds.add(result.record.fragment.id);
1996
- records.push(result.record);
1997
- fragments.push(result.record.fragment);
1998
- metadataByFragmentId[result.record.fragment.id] = recordMetadata(result.record);
1999
- }
2000
- return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
2156
+ );
2157
+ return {
2158
+ input: { records: opts.records, commands: opts.commands },
2159
+ projection,
2160
+ activeRecords: solutionProjection(
2161
+ graph,
2162
+ projection,
2163
+ `${name}/activeRecords`,
2164
+ "agenticMemoryRetentionActiveRecords",
2165
+ (fact) => fact.activeRecords
2166
+ ),
2167
+ archivedRecords: solutionProjection(
2168
+ graph,
2169
+ projection,
2170
+ `${name}/archivedRecords`,
2171
+ "agenticMemoryRetentionArchivedRecords",
2172
+ (fact) => fact.archivedRecords
2173
+ ),
2174
+ consolidationRequests: solutionProjection(
2175
+ graph,
2176
+ projection,
2177
+ `${name}/consolidationRequests`,
2178
+ "agenticMemoryRetentionConsolidationRequests",
2179
+ (fact) => fact.consolidationRequests
2180
+ ),
2181
+ status: solutionProjection(
2182
+ graph,
2183
+ projection,
2184
+ `${name}/status`,
2185
+ "agenticMemoryRetentionStatus",
2186
+ (fact) => fact.status
2187
+ ),
2188
+ errors: solutionProjection(
2189
+ graph,
2190
+ projection,
2191
+ `${name}/errors`,
2192
+ "agenticMemoryRetentionErrors",
2193
+ (fact) => fact.errors
2194
+ ),
2195
+ cursor: solutionProjection(
2196
+ graph,
2197
+ projection,
2198
+ `${name}/cursor`,
2199
+ "agenticMemoryRetentionCursor",
2200
+ (fact) => fact.cursor
2201
+ )
2202
+ };
2001
2203
  }
2002
- function validateAndSnapshotRecord(value, index) {
2003
- try {
2004
- return validateAndSnapshotRecordInner(value, index);
2005
- } catch (error) {
2204
+ function projectRetention(value, records) {
2205
+ const byId = new Map(records.map((record) => [record.id, record]));
2206
+ const view = new Map(records.map((record) => [record.id, record]));
2207
+ const requests = [];
2208
+ const errors = [];
2209
+ let validCommands = 0;
2210
+ let invalidCommands = 0;
2211
+ if (!Array.isArray(value)) {
2006
2212
  return {
2213
+ activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
2214
+ archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
2215
+ consolidationRequests: requests,
2216
+ validCommands,
2217
+ invalidCommands: 1,
2007
2218
  errors: [
2008
2219
  {
2009
- code: "invalid-record",
2010
- message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
2011
- index,
2012
- record: value,
2013
- validationErrors: Object.freeze(["record access failed"])
2220
+ code: "invalid-commands-input",
2221
+ message: "agenticMemoryRetentionBundle: commands input must be an array",
2222
+ command: value
2014
2223
  }
2015
2224
  ]
2016
2225
  };
2017
2226
  }
2018
- }
2019
- function validateAndSnapshotRecordInner(value, index) {
2020
- const errors = [];
2021
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
2227
+ const length = safeArrayLength(value);
2228
+ if (length === void 0) {
2022
2229
  return {
2230
+ activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
2231
+ archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
2232
+ consolidationRequests: requests,
2233
+ validCommands,
2234
+ invalidCommands: 1,
2023
2235
  errors: [
2024
2236
  {
2025
- code: "invalid-record",
2026
- message: "agenticMemoryBundle: record must be an object",
2027
- index,
2028
- record: value
2237
+ code: "invalid-commands-input",
2238
+ message: "agenticMemoryRetentionBundle: commands input length could not be read",
2239
+ command: value
2029
2240
  }
2030
2241
  ]
2031
2242
  };
2032
2243
  }
2033
- const record = value;
2034
- const recordId = typeof record.id === "string" ? record.id : void 0;
2035
- if (recordId === void 0 || recordId.length === 0) {
2036
- errors.push({
2037
- code: "invalid-record",
2038
- message: "agenticMemoryBundle: record.id must be a non-empty string",
2039
- index,
2040
- record: value,
2041
- validationErrors: ["record.id must be a non-empty string"]
2042
- });
2043
- }
2044
- if (!isAgenticMemoryKind(record.kind)) {
2045
- errors.push({
2046
- code: "invalid-record-kind",
2047
- message: "agenticMemoryBundle: record.kind is invalid",
2048
- index,
2049
- recordId,
2050
- record: value,
2051
- validationErrors: ["kind must be one of working, episodic, semantic, procedural, profile"]
2052
- });
2053
- }
2054
- if (!isAgenticMemoryPersistenceLevel(record.persistenceLevel)) {
2055
- errors.push({
2056
- code: "invalid-persistence-level",
2057
- message: "agenticMemoryBundle: record.persistenceLevel is invalid",
2058
- index,
2059
- recordId,
2060
- record: value,
2061
- validationErrors: [
2062
- "persistenceLevel must be one of turn, session, project, longTerm, permanent, archived"
2063
- ]
2064
- });
2065
- }
2066
- if (!isAgenticMemoryArtifactKind(record.artifactKind)) {
2067
- errors.push({
2068
- code: "invalid-artifact-kind",
2069
- message: "agenticMemoryBundle: record.artifactKind is invalid",
2070
- index,
2071
- recordId,
2072
- record: value,
2073
- validationErrors: ["artifactKind must be one of raw, insight, profile, procedure"]
2074
- });
2075
- }
2076
- const scopeValidation = validateScope(record.scope);
2077
- if (!scopeValidation.ok) {
2078
- errors.push({
2079
- code: "invalid-scope",
2080
- message: "agenticMemoryBundle: record.scope is invalid",
2081
- index,
2082
- recordId,
2083
- record: value,
2084
- validationErrors: Object.freeze(scopeValidation.errors)
2085
- });
2086
- }
2087
- const fragmentValidation = validateMemoryFragment(record.fragment);
2088
- if (!fragmentValidation.ok) {
2089
- errors.push({
2090
- code: "invalid-fragment",
2091
- message: "agenticMemoryBundle: record.fragment is invalid",
2092
- index,
2093
- recordId,
2094
- fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
2095
- record: value,
2096
- validationErrors: Object.freeze([...fragmentValidation.errors])
2097
- });
2098
- }
2099
- const forbiddenFields = [
2100
- "storageTier",
2101
- "storageKey",
2102
- "adapter",
2103
- "collection",
2104
- "collections",
2105
- "ttl",
2106
- "ttlMs",
2107
- "ttlNs",
2108
- "expiresAt",
2109
- "timer",
2110
- "scheduler",
2111
- "schedule",
2112
- "retentionTimer",
2113
- "consolidationSchedule",
2114
- "reflectionSchedule",
2115
- "llm",
2116
- "llmHandle",
2117
- "tool",
2118
- "toolHandle",
2119
- "runner",
2120
- "runnerHandle",
2121
- "restore",
2122
- "hydrate",
2123
- "hydration",
2124
- "graphMutation",
2125
- "protocol"
2126
- ];
2127
- const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
2128
- if (presentForbidden.length > 0) {
2129
- errors.push({
2130
- code: "invalid-record",
2131
- message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
2132
- index,
2133
- recordId,
2134
- record: value,
2135
- validationErrors: Object.freeze(
2136
- presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
2137
- )
2138
- });
2244
+ const seenCommands = /* @__PURE__ */ new Set();
2245
+ for (let i = 0; i < length; i += 1) {
2246
+ let raw;
2247
+ try {
2248
+ raw = value[i];
2249
+ const result = validateRetentionCommand(raw, i);
2250
+ if (result.errors.length > 0 || result.command === void 0) {
2251
+ invalidCommands += 1;
2252
+ errors.push(...result.errors);
2253
+ continue;
2254
+ }
2255
+ const command = result.command;
2256
+ if (seenCommands.has(command.id)) {
2257
+ invalidCommands += 1;
2258
+ errors.push({
2259
+ code: "duplicate-command-id",
2260
+ message: "agenticMemoryRetentionBundle: duplicate command id",
2261
+ index: i,
2262
+ commandId: command.id,
2263
+ command: raw,
2264
+ validationErrors: [`duplicate command id '${command.id}'`]
2265
+ });
2266
+ continue;
2267
+ }
2268
+ const missing = retentionMissingRecords(command, byId);
2269
+ if (missing.length > 0) {
2270
+ invalidCommands += 1;
2271
+ errors.push({
2272
+ code: "missing-record-ref",
2273
+ message: "agenticMemoryRetentionBundle: command references missing records",
2274
+ index: i,
2275
+ commandId: command.id,
2276
+ recordId: "recordId" in command ? command.recordId : void 0,
2277
+ recordIds: Object.freeze(missing),
2278
+ command: raw,
2279
+ validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
2280
+ });
2281
+ continue;
2282
+ }
2283
+ seenCommands.add(command.id);
2284
+ validCommands += 1;
2285
+ applyRetentionCommand(command, byId, view, requests);
2286
+ } catch (error) {
2287
+ invalidCommands += 1;
2288
+ errors.push({
2289
+ code: "invalid-command",
2290
+ message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage(error)}`,
2291
+ index: i,
2292
+ command: raw,
2293
+ validationErrors: ["command access failed"]
2294
+ });
2295
+ }
2139
2296
  }
2140
- if (errors.length > 0) return { errors };
2141
- const scope = scopeValidation.scope;
2142
- const fragment = snapshotFragment(record.fragment);
2297
+ const projected = records.map((record) => view.get(record.id) ?? record);
2143
2298
  return {
2144
- record: Object.freeze({
2145
- id: recordId,
2146
- kind: record.kind,
2147
- persistenceLevel: record.persistenceLevel,
2148
- artifactKind: record.artifactKind,
2149
- ...scope === void 0 ? {} : { scope },
2150
- fragment
2151
- }),
2152
- errors
2299
+ activeRecords: projected.filter((record) => record.persistenceLevel !== "archived"),
2300
+ archivedRecords: projected.filter((record) => record.persistenceLevel === "archived"),
2301
+ consolidationRequests: requests,
2302
+ errors,
2303
+ validCommands,
2304
+ invalidCommands
2153
2305
  };
2154
2306
  }
2155
- function snapshotFragment(fragment) {
2156
- return Object.freeze({
2157
- id: fragment.id,
2158
- payload: fragment.payload,
2159
- tNs: fragment.tNs,
2160
- ...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
2161
- ...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
2162
- confidence: fragment.confidence,
2163
- tags: Object.freeze([...fragment.tags]),
2164
- sources: Object.freeze([...fragment.sources]),
2165
- ...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
2166
- ...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
2167
- ...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
2168
- });
2169
- }
2170
- function recordMetadata(record) {
2171
- return Object.freeze({
2172
- recordId: record.id,
2173
- kind: record.kind,
2174
- persistenceLevel: record.persistenceLevel,
2175
- artifactKind: record.artifactKind,
2176
- ...record.scope === void 0 ? {} : { scope: record.scope }
2177
- });
2178
- }
2179
- function validateRecordMetadata(value) {
2180
- if (value === void 0) return { ok: true, errors: [] };
2307
+ function validateRetentionCommand(value, index) {
2181
2308
  if (!isPlainRecord(value)) {
2182
- return { ok: false, errors: ["record metadata must be an object when present"] };
2309
+ return {
2310
+ errors: [
2311
+ {
2312
+ code: "invalid-command",
2313
+ message: "agenticMemoryRetentionBundle: command must be an object",
2314
+ index,
2315
+ command: value
2316
+ }
2317
+ ]
2318
+ };
2183
2319
  }
2320
+ const id = typeof value.id === "string" && value.id.length > 0 ? value.id : void 0;
2321
+ const kind = value.kind;
2184
2322
  const errors = [];
2185
- for (const key of Object.keys(value)) {
2186
- if (key !== "recordId" && key !== "kind" && key !== "persistenceLevel" && key !== "artifactKind" && key !== "scope") {
2187
- errors.push(`record.${key} is not part of AgenticMemoryRecordMetadata`);
2188
- }
2323
+ if (id === void 0) errors.push("command.id must be a non-empty string");
2324
+ if (kind !== "archive" && kind !== "restore" && kind !== "setPersistenceLevel" && kind !== "requestConsolidation") {
2325
+ errors.push("command.kind is invalid");
2189
2326
  }
2190
- if (!isNonEmptyString(value.recordId)) {
2191
- errors.push("record.recordId must be a non-empty string");
2327
+ if (value.reason !== void 0 && typeof value.reason !== "string") {
2328
+ errors.push("command.reason must be a string when present");
2192
2329
  }
2193
- if (!isAgenticMemoryKind(value.kind)) {
2194
- errors.push("record.kind is invalid");
2330
+ if (kind === "archive") {
2331
+ if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
2332
+ } else if (kind === "restore") {
2333
+ if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
2334
+ if (value.persistenceLevel !== void 0 && (!isAgenticMemoryPersistenceLevel(value.persistenceLevel) || value.persistenceLevel === "archived")) {
2335
+ errors.push("restore.persistenceLevel must be a non-archived persistence level when present");
2336
+ }
2337
+ } else if (kind === "setPersistenceLevel") {
2338
+ if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
2339
+ if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
2340
+ errors.push("setPersistenceLevel.persistenceLevel is invalid");
2341
+ }
2342
+ } else if (kind === "requestConsolidation") {
2343
+ if (!isDenseArrayOf(value.recordIds, isNonEmptyString) || value.recordIds.length === 0) {
2344
+ errors.push("requestConsolidation.recordIds must be a non-empty string array");
2345
+ }
2346
+ if (value.requestId !== void 0 && (typeof value.requestId !== "string" || value.requestId.length === 0)) {
2347
+ errors.push("requestConsolidation.requestId must be non-empty when present");
2348
+ }
2195
2349
  }
2196
- if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
2197
- errors.push("record.persistenceLevel is invalid");
2350
+ if (errors.length > 0 || id === void 0) {
2351
+ return {
2352
+ errors: [
2353
+ {
2354
+ code: "invalid-command",
2355
+ message: "agenticMemoryRetentionBundle: command is invalid",
2356
+ index,
2357
+ commandId: id,
2358
+ command: value,
2359
+ validationErrors: Object.freeze(errors)
2360
+ }
2361
+ ]
2362
+ };
2198
2363
  }
2199
- if (!isAgenticMemoryArtifactKind(value.artifactKind)) {
2200
- errors.push("record.artifactKind is invalid");
2364
+ const base = { id, reason: value.reason };
2365
+ if (kind === "archive") {
2366
+ return {
2367
+ command: Object.freeze({
2368
+ ...base,
2369
+ kind,
2370
+ recordId: value.recordId,
2371
+ ...base.reason === void 0 ? {} : { reason: base.reason }
2372
+ }),
2373
+ errors: []
2374
+ };
2201
2375
  }
2202
- const scopeValidation = validateScope(value.scope);
2203
- if (!scopeValidation.ok) {
2204
- errors.push(...scopeValidation.errors.map((error) => `record.${error}`));
2376
+ if (kind === "restore") {
2377
+ return {
2378
+ command: Object.freeze({
2379
+ ...base,
2380
+ kind,
2381
+ recordId: value.recordId,
2382
+ ...value.persistenceLevel === void 0 ? {} : {
2383
+ persistenceLevel: value.persistenceLevel
2384
+ },
2385
+ ...base.reason === void 0 ? {} : { reason: base.reason }
2386
+ }),
2387
+ errors: []
2388
+ };
2389
+ }
2390
+ if (kind === "setPersistenceLevel") {
2391
+ return {
2392
+ command: Object.freeze({
2393
+ ...base,
2394
+ kind,
2395
+ recordId: value.recordId,
2396
+ persistenceLevel: value.persistenceLevel,
2397
+ ...base.reason === void 0 ? {} : { reason: base.reason }
2398
+ }),
2399
+ errors: []
2400
+ };
2205
2401
  }
2206
- if (errors.length > 0) return { ok: false, errors };
2207
2402
  return {
2208
- ok: true,
2209
- errors,
2210
- metadata: Object.freeze({
2211
- recordId: value.recordId,
2212
- kind: value.kind,
2213
- persistenceLevel: value.persistenceLevel,
2214
- artifactKind: value.artifactKind,
2215
- ...scopeValidation.scope === void 0 ? {} : { scope: scopeValidation.scope }
2216
- })
2403
+ command: Object.freeze({
2404
+ ...base,
2405
+ kind: "requestConsolidation",
2406
+ recordIds: Object.freeze([...value.recordIds]),
2407
+ ...value.requestId === void 0 ? {} : { requestId: value.requestId },
2408
+ ...base.reason === void 0 ? {} : { reason: base.reason }
2409
+ }),
2410
+ errors: []
2217
2411
  };
2218
2412
  }
2219
- function contextState(projection, retrieval) {
2220
- if (projection === "error" || retrieval === "error") return "error";
2221
- if (projection === "partial" || retrieval === "partial") return "partial";
2222
- return retrieval;
2413
+ function retentionMissingRecords(command, records) {
2414
+ if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
2415
+ return command.recordIds.filter((recordId) => !records.has(recordId));
2223
2416
  }
2224
- function agenticStatusState(errorCount, validRecords) {
2225
- if (errorCount > 0 && validRecords === 0) return "error";
2226
- if (errorCount > 0) return "partial";
2227
- return validRecords > 0 ? "ready" : "empty";
2417
+ function applyRetentionCommand(command, source, view, requests) {
2418
+ if (command.kind === "requestConsolidation") {
2419
+ requests.push(
2420
+ Object.freeze({
2421
+ id: command.requestId ?? command.id,
2422
+ commandId: command.id,
2423
+ recordIds: Object.freeze([...command.recordIds]),
2424
+ ...command.reason === void 0 ? {} : { reason: command.reason }
2425
+ })
2426
+ );
2427
+ return;
2428
+ }
2429
+ const record = view.get(command.recordId) ?? source.get(command.recordId);
2430
+ if (record === void 0) return;
2431
+ const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
2432
+ view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
2228
2433
  }
2229
- function isAgenticMemoryKind(value) {
2230
- return value === "working" || value === "episodic" || value === "semantic" || value === "procedural" || value === "profile";
2434
+ function nonArchivedLevel(record) {
2435
+ return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
2231
2436
  }
2232
- function isAgenticMemoryPersistenceLevel(value) {
2233
- return value === "turn" || value === "session" || value === "project" || value === "longTerm" || value === "permanent" || value === "archived";
2437
+ function withPersistenceLevel(record, persistenceLevel) {
2438
+ return Object.freeze({
2439
+ ...record,
2440
+ persistenceLevel
2441
+ });
2234
2442
  }
2235
- function isAgenticMemoryArtifactKind(value) {
2236
- return value === "raw" || value === "insight" || value === "profile" || value === "procedure";
2443
+ function retentionErrorFromRecordError(error) {
2444
+ return {
2445
+ ...error,
2446
+ code: error.code
2447
+ };
2448
+ }
2449
+
2450
+ // src/solutions/capability-admission.ts
2451
+ function capabilityAdmissionProposal(opts) {
2452
+ return { kind: "capability-admission-proposal", ...opts };
2453
+ }
2454
+ function capabilityAdmissionProjector(graph, opts) {
2455
+ const name = opts.name ?? "capabilityAdmissions";
2456
+ const policyDeps = opts.admissionPolicies ?? [];
2457
+ const now = opts.now ?? Date.now;
2458
+ const runtime = graph.node(
2459
+ [opts.proposals, opts.decisions, ...policyDeps],
2460
+ (ctx) => {
2461
+ const state = ctx.state.get() ?? emptyCapabilityAdmissionState();
2462
+ for (const raw of depBatch(ctx, 0) ?? []) {
2463
+ const proposal = raw;
2464
+ const issue = capabilityAdmissionProposalIssue(proposal);
2465
+ if (issue !== void 0) {
2466
+ emitIssue(
2467
+ ctx,
2468
+ state,
2469
+ nextMalformedIssueKey(state, "proposal", proposalKeyFallback(proposal)),
2470
+ issue
2471
+ );
2472
+ continue;
2473
+ }
2474
+ if (state.proposals.has(proposal.proposalId)) {
2475
+ emitIssue(
2476
+ ctx,
2477
+ state,
2478
+ `duplicate-proposal:${proposal.proposalId}`,
2479
+ dataIssue(
2480
+ "duplicate-capability-admission-proposal",
2481
+ `CapabilityAdmissionProposal '${proposal.proposalId}' was already seen`,
2482
+ { subjectId: proposal.subjectId, refs: capabilityProposalRefs(proposal) }
2483
+ )
2484
+ );
2485
+ continue;
2486
+ }
2487
+ state.proposals.set(proposal.proposalId, proposal);
2488
+ }
2489
+ forEachPolicyDepBatch(ctx, 2, policyDeps.length, (raw) => {
2490
+ const policy = raw;
2491
+ const issue = capabilityAdmissionPolicyIssue(policy);
2492
+ if (issue !== void 0) {
2493
+ emitIssue(
2494
+ ctx,
2495
+ state,
2496
+ nextMalformedIssueKey(state, "policy", policyKeyFallback(policy)),
2497
+ issue
2498
+ );
2499
+ return;
2500
+ }
2501
+ if (state.policies.has(policy.policyId)) {
2502
+ emitIssue(
2503
+ ctx,
2504
+ state,
2505
+ `duplicate-policy:${policy.policyId}`,
2506
+ dataIssue(
2507
+ "duplicate-capability-admission-policy",
2508
+ `CapabilityAdmissionPolicy '${policy.policyId}' was already seen`,
2509
+ { refs: [ref("capability-admission-policy", policy.policyId)] }
2510
+ )
2511
+ );
2512
+ return;
2513
+ }
2514
+ state.policies.set(policy.policyId, policy);
2515
+ });
2516
+ for (const raw of depBatch(ctx, 1) ?? []) {
2517
+ const decision = raw;
2518
+ const issue = capabilityAdmissionDecisionIssue(decision);
2519
+ if (issue !== void 0) {
2520
+ emitIssue(
2521
+ ctx,
2522
+ state,
2523
+ nextMalformedIssueKey(state, "decision", decisionKeyFallback(decision)),
2524
+ issue
2525
+ );
2526
+ continue;
2527
+ }
2528
+ if (state.decisions.has(decision.decisionId)) {
2529
+ emitIssue(
2530
+ ctx,
2531
+ state,
2532
+ `duplicate-decision:${decision.decisionId}`,
2533
+ dataIssue(
2534
+ "duplicate-capability-admission-decision",
2535
+ `CapabilityAdmissionDecision '${decision.decisionId}' was already seen`,
2536
+ { refs: capabilityDecisionRefs(decision) }
2537
+ )
2538
+ );
2539
+ continue;
2540
+ }
2541
+ state.decisions.set(decision.decisionId, decision);
2542
+ }
2543
+ evaluateCapabilityAdmissions(ctx, state, now());
2544
+ ctx.state.set(state);
2545
+ },
2546
+ { name: `${name}/runtime`, factory: "capabilityAdmissionProjector", partial: true }
2547
+ );
2548
+ return {
2549
+ admissions: projectRuntimeFact(
2550
+ graph,
2551
+ runtime,
2552
+ `${name}/admissions`,
2553
+ "capabilityAdmissions",
2554
+ (fact) => fact.kind === "admission" ? fact.admission : void 0
2555
+ ),
2556
+ status: projectRuntimeFact(
2557
+ graph,
2558
+ runtime,
2559
+ `${name}/status`,
2560
+ "capabilityAdmissionStatus",
2561
+ (fact) => fact.kind === "status" ? fact.status : void 0
2562
+ ),
2563
+ issues: projectRuntimeFact(
2564
+ graph,
2565
+ runtime,
2566
+ `${name}/issues`,
2567
+ "capabilityAdmissionIssues",
2568
+ (fact) => fact.kind === "issue" ? fact.issue : void 0
2569
+ ),
2570
+ audit: projectRuntimeFact(
2571
+ graph,
2572
+ runtime,
2573
+ `${name}/audit`,
2574
+ "capabilityAdmissionAudit",
2575
+ (fact) => fact.kind === "audit" ? fact.audit : void 0
2576
+ ),
2577
+ views: capabilityAdmissionViews(graph, runtime, `${name}/views`)
2578
+ };
2237
2579
  }
2238
- function validateScope(value) {
2239
- if (value === void 0) return { ok: true, errors: [] };
2240
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
2241
- return { ok: false, errors: ["scope must be an object when present"] };
2580
+ function evaluateCapabilityAdmissions(ctx, state, admittedAtMs) {
2581
+ for (const decision of state.decisions.values()) {
2582
+ if (state.terminalDecisionIds.has(decision.decisionId)) continue;
2583
+ evaluateCapabilityAdmission(ctx, state, decision, admittedAtMs);
2584
+ }
2585
+ }
2586
+ function evaluateCapabilityAdmission(ctx, state, decision, admittedAtMs) {
2587
+ const proposal = state.proposals.get(decision.proposalId);
2588
+ if (proposal === void 0) {
2589
+ emitIssue(
2590
+ ctx,
2591
+ state,
2592
+ `missing-proposal:${decision.decisionId}:${decision.proposalId}`,
2593
+ dataIssue(
2594
+ "missing-capability-admission-proposal",
2595
+ `CapabilityAdmissionDecision '${decision.decisionId}' references missing proposal '${decision.proposalId}'`,
2596
+ { subjectId: decision.proposalId, refs: capabilityDecisionRefs(decision) }
2597
+ )
2598
+ );
2599
+ return;
2242
2600
  }
2243
- const scope = value;
2244
- const errors = [];
2245
- const allowed = /* @__PURE__ */ new Set(["sessionId", "projectId", "userId", "tenantId"]);
2246
- for (const key of Object.keys(scope)) {
2247
- if (!allowed.has(key)) errors.push(`scope.${key} is not part of AgenticMemoryScope`);
2601
+ const policy = capabilityPolicyForDecision(state, decision);
2602
+ if (typeof policy === "string") {
2603
+ emitIssue(
2604
+ ctx,
2605
+ state,
2606
+ `${policy}:${decision.decisionId}:${decision.policyId ?? "missing"}`,
2607
+ dataIssue(policy, capabilityPolicyIssueMessage(policy, decision), {
2608
+ subjectId: proposal.subjectId,
2609
+ refs: capabilityDecisionRefs(decision, proposal)
2610
+ })
2611
+ );
2612
+ if (policy === "stale-capability-admission-policy-ref")
2613
+ state.terminalDecisionIds.add(decision.decisionId);
2614
+ return;
2248
2615
  }
2249
- for (const key of allowed) {
2250
- if (scope[key] !== void 0 && (typeof scope[key] !== "string" || scope[key].length === 0)) {
2251
- errors.push(`scope.${key} must be a non-empty string when present`);
2616
+ if (policy !== void 0) {
2617
+ const policyIssue = validateCapabilityAdmissionPolicy(policy, decision, proposal);
2618
+ if (policyIssue !== void 0) {
2619
+ emitIssue(
2620
+ ctx,
2621
+ state,
2622
+ `${policyIssue.code}:${decision.decisionId}:${policy.policyId}`,
2623
+ dataIssue(policyIssue.code, policyIssue.message, {
2624
+ subjectId: proposal.subjectId,
2625
+ refs: capabilityDecisionRefs(decision, proposal, policy)
2626
+ })
2627
+ );
2628
+ return;
2252
2629
  }
2253
2630
  }
2254
- if (errors.length > 0) return { ok: false, errors };
2255
- return {
2256
- ok: true,
2257
- errors,
2258
- scope: Object.freeze({
2259
- ...scope.sessionId === void 0 ? {} : { sessionId: scope.sessionId },
2260
- ...scope.projectId === void 0 ? {} : { projectId: scope.projectId },
2261
- ...scope.userId === void 0 ? {} : { userId: scope.userId },
2262
- ...scope.tenantId === void 0 ? {} : { tenantId: scope.tenantId }
2263
- })
2264
- };
2265
- }
2266
- function isPlainRecord(value) {
2267
- return value !== null && typeof value === "object" && !Array.isArray(value);
2268
- }
2269
- function ownKeys(value) {
2270
- return Object.keys(value).sort();
2271
- }
2272
- function assertExactKeys(value, expected, label) {
2273
- const actual = ownKeys(value);
2274
- const want = [...expected].sort();
2275
- if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
2276
- throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
2631
+ if (state.admissionsById.has(decision.admissionId)) {
2632
+ emitIssue(
2633
+ ctx,
2634
+ state,
2635
+ `duplicate-admission-id:${decision.admissionId}`,
2636
+ dataIssue(
2637
+ "duplicate-capability-admission",
2638
+ `CapabilityAdmission '${decision.admissionId}' was already emitted`,
2639
+ { subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
2640
+ )
2641
+ );
2642
+ state.terminalDecisionIds.add(decision.decisionId);
2643
+ return;
2277
2644
  }
2278
- }
2279
- function assertAgenticMemoryRecordCodecShape(value) {
2280
- if (!isPlainRecord(value)) {
2281
- throw new TypeError("agenticMemoryRecordFrame: record must be an object");
2645
+ if (state.admissionsByProposal.has(decision.proposalId)) {
2646
+ emitIssue(
2647
+ ctx,
2648
+ state,
2649
+ `duplicate-admission-proposal:${decision.proposalId}:${decision.decisionId}`,
2650
+ dataIssue(
2651
+ "duplicate-capability-admission-proposal",
2652
+ `CapabilityAdmissionProposal '${decision.proposalId}' already has an admission decision`,
2653
+ { subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
2654
+ )
2655
+ );
2656
+ state.terminalDecisionIds.add(decision.decisionId);
2657
+ return;
2282
2658
  }
2283
- assertNoSymbolKeys(value, "agenticMemoryRecordFrame.record");
2284
- assertExactKeys(
2285
- value,
2286
- value.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
2287
- "agenticMemoryRecordFrame.record"
2288
- );
2289
- const fragment = value.fragment;
2290
- if (!isPlainRecord(fragment)) {
2291
- throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
2659
+ const admissionState = admissionStateForOutcome(decision.outcome);
2660
+ if (admissionState === void 0) {
2661
+ emitIssue(
2662
+ ctx,
2663
+ state,
2664
+ `unsupported-outcome:${decision.decisionId}:${String(decision.outcome)}`,
2665
+ dataIssue(
2666
+ "unsupported-capability-admission-outcome",
2667
+ `CapabilityAdmissionDecision '${decision.decisionId}' uses unsupported outcome '${String(decision.outcome)}'`,
2668
+ { subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
2669
+ )
2670
+ );
2671
+ state.terminalDecisionIds.add(decision.decisionId);
2672
+ return;
2292
2673
  }
2293
- assertNoSymbolKeys(fragment, "agenticMemoryRecordFrame.record.fragment");
2294
- assertExactKeys(
2295
- fragment,
2296
- [
2297
- "id",
2298
- "payload",
2299
- "tNs",
2300
- ...fragment.validFrom === void 0 ? [] : ["validFrom"],
2301
- ...fragment.validTo === void 0 ? [] : ["validTo"],
2302
- "confidence",
2303
- "tags",
2304
- "sources",
2305
- ...fragment.embedding === void 0 ? [] : ["embedding"],
2306
- ...fragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
2307
- ...fragment.provenance === void 0 ? [] : ["provenance"]
2308
- ],
2309
- "agenticMemoryRecordFrame.record.fragment"
2674
+ const admission = {
2675
+ kind: "capability-admission",
2676
+ admissionId: decision.admissionId,
2677
+ proposalId: proposal.proposalId,
2678
+ subjectId: proposal.subjectId,
2679
+ capability: cloneCapabilityRef(proposal.capability),
2680
+ state: admissionState,
2681
+ decisionId: decision.decisionId,
2682
+ boundaryName: proposal.boundaryName,
2683
+ role: proposal.role,
2684
+ policyId: decision.policyId,
2685
+ reason: decision.reason ?? proposal.reason,
2686
+ sourceRefs: capabilityDecisionRefs(decision, proposal, policy),
2687
+ admittedAtMs: decision.decidedAtMs ?? admittedAtMs,
2688
+ metadata: {
2689
+ ...proposal.metadata ?? {},
2690
+ ...policy?.metadata ?? {},
2691
+ ...decision.metadata ?? {}
2692
+ }
2693
+ };
2694
+ state.admissionsById.set(admission.admissionId, admission);
2695
+ state.admissionsByProposal.set(admission.proposalId, admission);
2696
+ state.terminalDecisionIds.add(decision.decisionId);
2697
+ emitAdmission(ctx, state, admission);
2698
+ }
2699
+ function capabilityAdmissionViews(graph, runtime, name) {
2700
+ return graph.node(
2701
+ [runtime],
2702
+ (ctx) => {
2703
+ const state = ctx.state.get() ?? {
2704
+ admissionsByProposal: /* @__PURE__ */ new Map(),
2705
+ admissionsBySubject: /* @__PURE__ */ new Map(),
2706
+ issues: [],
2707
+ audit: []
2708
+ };
2709
+ for (const raw of depBatch(ctx, 0) ?? []) {
2710
+ const fact = raw;
2711
+ if (fact.kind === "admission") {
2712
+ const admission = fact.admission;
2713
+ state.admissionsByProposal.set(admission.proposalId, admission);
2714
+ const bySubject = state.admissionsBySubject.get(admission.subjectId) ?? [];
2715
+ bySubject.push(admission);
2716
+ state.admissionsBySubject.set(admission.subjectId, bySubject);
2717
+ }
2718
+ if (fact.kind === "issue") state.issues.push(fact.issue);
2719
+ if (fact.kind === "audit") state.audit.push(fact.audit);
2720
+ }
2721
+ ctx.state.set(state);
2722
+ ctx.down([["DATA", freezeCapabilityAdmissionViews(state)]]);
2723
+ },
2724
+ { name, factory: "capabilityAdmissionViews" }
2310
2725
  );
2311
- assertStrictJsonValue(fragment.tags, "record.fragment.tags");
2312
- assertStrictJsonValue(fragment.sources, "record.fragment.sources");
2313
- if (fragment.embedding !== void 0) {
2314
- assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
2315
- }
2316
- if (value.scope !== void 0) assertScopeFrame(value.scope);
2317
2726
  }
2318
- function assertNoSymbolKeys(value, label) {
2319
- if (Object.getOwnPropertySymbols(value).length > 0) {
2320
- throw new TypeError(`${label}: unexpected symbol fields`);
2727
+ function emitAdmission(ctx, state, admission) {
2728
+ state.statusSeq += 1;
2729
+ state.auditSeq += 1;
2730
+ const statusState = capabilityAdmissionStatusState(admission.state);
2731
+ const status = {
2732
+ kind: "capability-admission-status",
2733
+ statusId: `${admission.subjectId}:${statusState}:${state.statusSeq}`,
2734
+ state: statusState,
2735
+ proposalId: admission.proposalId,
2736
+ admissionId: admission.admissionId,
2737
+ subjectId: admission.subjectId,
2738
+ capabilityId: admission.capability.id,
2739
+ capabilityKind: admission.capability.kind,
2740
+ policyId: admission.policyId,
2741
+ sourceRefs: admission.sourceRefs
2742
+ };
2743
+ const audit = {
2744
+ id: `${admission.subjectId}:${statusState}:${state.auditSeq}`,
2745
+ kind: `capability-admission-${admission.state}`,
2746
+ subjectId: admission.subjectId,
2747
+ sourceRefs: admission.sourceRefs,
2748
+ metadata: {
2749
+ admissionId: admission.admissionId,
2750
+ capabilityId: admission.capability.id,
2751
+ capabilityKind: admission.capability.kind,
2752
+ policyId: admission.policyId,
2753
+ proposalId: admission.proposalId
2754
+ }
2755
+ };
2756
+ ctx.down([
2757
+ ["DATA", { kind: "admission", admission }],
2758
+ ["DATA", { kind: "status", status }],
2759
+ ["DATA", { kind: "audit", audit }]
2760
+ ]);
2761
+ }
2762
+ function emitIssue(ctx, state, key, issue) {
2763
+ if (state.issueKeys.has(key)) return;
2764
+ state.issueKeys.add(key);
2765
+ state.statusSeq += 1;
2766
+ state.auditSeq += 1;
2767
+ const status = {
2768
+ kind: "capability-admission-status",
2769
+ statusId: `capability-admission-issue:${state.statusSeq}`,
2770
+ state: "capability-admission-issue",
2771
+ subjectId: issue.subjectId,
2772
+ issues: [issue]
2773
+ };
2774
+ const audit = {
2775
+ id: `capability-admission-issue:${state.auditSeq}`,
2776
+ kind: "capability-admission-issue",
2777
+ subjectId: issue.subjectId,
2778
+ message: issue.message,
2779
+ issueCode: issue.code
2780
+ };
2781
+ ctx.down([
2782
+ ["DATA", { kind: "issue", issue }],
2783
+ ["DATA", { kind: "status", status }],
2784
+ ["DATA", { kind: "audit", audit }]
2785
+ ]);
2786
+ }
2787
+ function capabilityAdmissionProposalIssue(proposal) {
2788
+ if (proposal.kind !== "capability-admission-proposal" || typeof proposal.proposalId !== "string" || proposal.proposalId.length === 0 || typeof proposal.subjectId !== "string" || proposal.subjectId.length === 0 || !isBoundaryCapabilityRef(proposal.capability)) {
2789
+ return dataIssue(
2790
+ "malformed-capability-admission-proposal",
2791
+ "CapabilityAdmissionProposal requires proposalId, subjectId, and a D348 BoundaryCapabilityRef",
2792
+ { subjectId: typeof proposal.subjectId === "string" ? proposal.subjectId : void 0 }
2793
+ );
2321
2794
  }
2795
+ return void 0;
2322
2796
  }
2323
- function decimalBigIntString(value, label) {
2324
- const out = value.toString(10);
2325
- if (!/^-?(0|[1-9]\d*)$/.test(out)) {
2326
- throw new TypeError(`${label} must encode as a canonical decimal bigint string`);
2797
+ function capabilityAdmissionPolicyIssue(policy) {
2798
+ if (policy.kind !== "capability-admission-policy" || typeof policy.policyId !== "string" || policy.policyId.length === 0 || policy.capabilityIds !== void 0 && (!Array.isArray(policy.capabilityIds) || !policy.capabilityIds.every((id) => typeof id === "string" && id.length > 0)) || policy.capabilityKinds !== void 0 && (!Array.isArray(policy.capabilityKinds) || !policy.capabilityKinds.every(isBoundaryCapabilityKind)) || policy.requiredOnly !== void 0 && typeof policy.requiredOnly !== "boolean" || policy.allowedOutcomes !== void 0 && (!Array.isArray(policy.allowedOutcomes) || !policy.allowedOutcomes.every(isCapabilityAdmissionOutcome))) {
2799
+ return dataIssue(
2800
+ "malformed-capability-admission-policy",
2801
+ "CapabilityAdmissionPolicy requires a policyId and D348 capability/outcome filters",
2802
+ { subjectId: typeof policy.policyId === "string" ? policy.policyId : void 0 }
2803
+ );
2327
2804
  }
2328
- return out;
2805
+ return void 0;
2329
2806
  }
2330
- function parseDecimalBigInt(value, label) {
2331
- if (typeof value !== "string" || !/^(0|-?[1-9]\d*)$/.test(value)) {
2332
- throw new TypeError(`${label} must be a canonical decimal bigint string`);
2807
+ function capabilityAdmissionDecisionIssue(decision) {
2808
+ if (decision.kind !== "capability-admission-decision" || typeof decision.decisionId !== "string" || decision.decisionId.length === 0 || typeof decision.admissionId !== "string" || decision.admissionId.length === 0 || typeof decision.proposalId !== "string" || decision.proposalId.length === 0 || !isCapabilityAdmissionOutcome(decision.outcome) || decision.policyId !== void 0 && (typeof decision.policyId !== "string" || decision.policyId.length === 0)) {
2809
+ return dataIssue(
2810
+ "malformed-capability-admission-decision",
2811
+ "CapabilityAdmissionDecision requires decisionId, admissionId, proposalId, and allow/block/defer outcome",
2812
+ { subjectId: typeof decision.proposalId === "string" ? decision.proposalId : void 0 }
2813
+ );
2333
2814
  }
2334
- return BigInt(value);
2815
+ return void 0;
2335
2816
  }
2336
- function assertStrictJsonValue(value, label) {
2337
- try {
2338
- strictJsonCodec.encode(value);
2339
- return value;
2340
- } catch (error) {
2341
- throw new TypeError(`${label} must be strict JSON: ${errorMessage(error)}`);
2817
+ function validateCapabilityAdmissionPolicy(policy, decision, proposal) {
2818
+ if (policy.capabilityIds !== void 0 && !policy.capabilityIds.includes(proposal.capability.id)) {
2819
+ return {
2820
+ code: "capability-admission-policy-mismatch",
2821
+ message: `CapabilityAdmissionPolicy '${policy.policyId}' does not apply to capability '${proposal.capability.id}'`
2822
+ };
2342
2823
  }
2343
- }
2344
- function assertScopeFrame(value) {
2345
- if (!isPlainRecord(value)) {
2346
- throw new TypeError("agenticMemoryRecordFrame: scope must be an object when present");
2824
+ if (policy.capabilityKinds !== void 0 && !policy.capabilityKinds.includes(proposal.capability.kind)) {
2825
+ return {
2826
+ code: "capability-admission-policy-mismatch",
2827
+ message: `CapabilityAdmissionPolicy '${policy.policyId}' does not apply to capability kind '${proposal.capability.kind}'`
2828
+ };
2347
2829
  }
2348
- assertStrictJsonValue(value, "record.scope");
2349
- const validation = validateScope(value);
2350
- if (!validation.ok || validation.scope === void 0) {
2351
- throw new TypeError(`agenticMemoryRecordFrame: invalid scope: ${validation.errors.join("; ")}`);
2830
+ if (policy.requiredOnly === true && !proposal.capability.required) {
2831
+ return {
2832
+ code: "capability-admission-policy-mismatch",
2833
+ message: `CapabilityAdmissionPolicy '${policy.policyId}' applies only to required capabilities`
2834
+ };
2352
2835
  }
2353
- assertExactKeys(
2354
- value,
2355
- [
2356
- ...value.sessionId === void 0 ? [] : ["sessionId"],
2357
- ...value.projectId === void 0 ? [] : ["projectId"],
2358
- ...value.userId === void 0 ? [] : ["userId"],
2359
- ...value.tenantId === void 0 ? [] : ["tenantId"]
2360
- ],
2361
- "agenticMemoryRecordFrame.record.scope"
2836
+ if (policy.allowedOutcomes !== void 0 && !policy.allowedOutcomes.includes(decision.outcome)) {
2837
+ return {
2838
+ code: "unsupported-capability-admission-outcome",
2839
+ message: `CapabilityAdmissionPolicy '${policy.policyId}' does not allow outcome '${decision.outcome}'`
2840
+ };
2841
+ }
2842
+ return void 0;
2843
+ }
2844
+ function capabilityPolicyForDecision(state, decision) {
2845
+ if (decision.policyId === void 0) return void 0;
2846
+ const stalePolicyRef = (decision.sourceRefs ?? []).find(
2847
+ (sourceRef) => sourceRef.kind === "capability-admission-policy" && sourceRef.id !== decision.policyId
2362
2848
  );
2363
- return validation.scope;
2849
+ if (stalePolicyRef !== void 0) return "stale-capability-admission-policy-ref";
2850
+ return state.policies.get(decision.policyId) ?? "missing-capability-admission-policy";
2364
2851
  }
2365
- function assertKindValue(value) {
2366
- if (!isAgenticMemoryKind(value)) {
2367
- throw new TypeError("agenticMemoryRecordFrame: invalid memory kind");
2852
+ function capabilityPolicyIssueMessage(code, decision) {
2853
+ if (code === "missing-capability-admission-policy") {
2854
+ return `CapabilityAdmissionPolicy '${decision.policyId}' was referenced but not present`;
2368
2855
  }
2369
- return value;
2856
+ return `CapabilityAdmissionDecision '${decision.decisionId}' carries a stale admission policy source ref`;
2370
2857
  }
2371
- function assertPersistenceLevelValue(value) {
2372
- if (!isAgenticMemoryPersistenceLevel(value)) {
2373
- throw new TypeError("agenticMemoryRecordFrame: invalid persistence level");
2374
- }
2375
- return value;
2858
+ function admissionStateForOutcome(outcome) {
2859
+ if (outcome === "allow") return "allowed";
2860
+ if (outcome === "block") return "blocked";
2861
+ if (outcome === "defer") return "deferred";
2862
+ return void 0;
2376
2863
  }
2377
- function assertArtifactKindValue(value) {
2378
- if (!isAgenticMemoryArtifactKind(value)) {
2379
- throw new TypeError("agenticMemoryRecordFrame: invalid artifact kind");
2380
- }
2381
- return value;
2864
+ function capabilityAdmissionStatusState(state) {
2865
+ if (state === "allowed") return "capability-admission-allowed";
2866
+ if (state === "blocked") return "capability-admission-blocked";
2867
+ return "capability-admission-deferred";
2382
2868
  }
2383
- function assertNonEmptyString(value, label) {
2384
- if (!isNonEmptyString(value)) throw new TypeError(`${label} must be a non-empty string`);
2385
- return value;
2869
+ function cloneCapabilityRef(ref2) {
2870
+ return {
2871
+ id: ref2.id,
2872
+ kind: ref2.kind,
2873
+ required: ref2.required,
2874
+ ...ref2.sourceRefs === void 0 ? {} : { sourceRefs: [...ref2.sourceRefs] }
2875
+ };
2386
2876
  }
2387
- function assertString(value, label) {
2388
- if (typeof value !== "string") throw new TypeError(`${label} must be a string`);
2389
- return value;
2877
+ function isBoundaryCapabilityRef(value) {
2878
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
2879
+ const record = value;
2880
+ return typeof record.id === "string" && record.id.length > 0 && isBoundaryCapabilityKind(record.kind) && typeof record.required === "boolean" && (record.sourceRefs === void 0 || Array.isArray(record.sourceRefs) && record.sourceRefs.every((sourceRef) => typeof sourceRef === "string"));
2390
2881
  }
2391
- function assertConfidence(value, label) {
2392
- if (!Number.isFinite(value) || value < 0 || value > 1) {
2393
- throw new TypeError(`${label} must be a finite number in [0, 1]`);
2394
- }
2395
- return value;
2882
+ function isBoundaryCapabilityKind(value) {
2883
+ return value === "auth" || value === "permission" || value === "config" || value === "resource";
2396
2884
  }
2397
- function assertStringArray(value, label) {
2398
- if (!isDenseArrayOf(value, (item) => typeof item === "string")) {
2399
- throw new TypeError(`${label} must be a readonly string array`);
2400
- }
2401
- return Object.freeze([...value]);
2885
+ function isCapabilityAdmissionOutcome(value) {
2886
+ return value === "allow" || value === "block" || value === "defer";
2402
2887
  }
2403
- function assertFiniteNumberArray(value, label) {
2404
- if (!isDenseArrayOf(value, (item) => Number.isFinite(item))) {
2405
- throw new TypeError(`${label} must be a finite number array`);
2406
- }
2407
- return Object.freeze([...value]);
2888
+ function proposalKeyFallback(proposal) {
2889
+ return typeof proposal.proposalId === "string" && proposal.proposalId.length > 0 ? proposal.proposalId : `${stringValue(proposal.subjectId) ?? "unknown"}:${capabilityKeyFallback(proposal.capability)}`;
2408
2890
  }
2409
- function isNonEmptyString(value) {
2410
- return typeof value === "string" && value.length > 0;
2891
+ function policyKeyFallback(policy) {
2892
+ return typeof policy.policyId === "string" && policy.policyId.length > 0 ? policy.policyId : "unknown";
2411
2893
  }
2412
- function isDenseArrayOf(value, predicate) {
2413
- if (!Array.isArray(value)) return false;
2414
- for (let i = 0; i < value.length; i += 1) {
2415
- if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
2894
+ function decisionKeyFallback(decision) {
2895
+ return typeof decision.decisionId === "string" && decision.decisionId.length > 0 ? decision.decisionId : `${stringValue(decision.proposalId) ?? "unknown"}:${stringValue(decision.admissionId) ?? "unknown"}`;
2896
+ }
2897
+ function capabilityKeyFallback(value) {
2898
+ if (!isBoundaryCapabilityRef(value)) return "unknown-capability";
2899
+ return `${value.kind}:${value.id}`;
2900
+ }
2901
+ function nextMalformedIssueKey(state, kind, fallback) {
2902
+ state.issueSeq += 1;
2903
+ return `malformed-${kind}:${state.issueSeq}:${fallback}`;
2904
+ }
2905
+ function stringValue(value) {
2906
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2907
+ }
2908
+ function capabilityProposalRefs(proposal) {
2909
+ return uniqueSourceRefs([
2910
+ ref("capability-admission-proposal", proposal.proposalId),
2911
+ ref("boundary-capability", `${proposal.capability.kind}:${proposal.capability.id}`),
2912
+ ...proposal.sourceRefs ?? []
2913
+ ]);
2914
+ }
2915
+ function capabilityDecisionRefs(decision, proposal, policy) {
2916
+ return uniqueSourceRefs([
2917
+ ref("capability-admission-decision", decision.decisionId),
2918
+ ref("capability-admission", decision.admissionId),
2919
+ ref("capability-admission-proposal", decision.proposalId),
2920
+ ...proposal === void 0 ? [] : capabilityProposalRefs(proposal),
2921
+ ...decision.policyId === void 0 ? [] : [ref("capability-admission-policy", decision.policyId)],
2922
+ ...policy === void 0 ? [] : [ref("capability-admission-policy", policy.policyId)],
2923
+ ...decision.sourceRefs ?? []
2924
+ ]);
2925
+ }
2926
+ function forEachPolicyDepBatch(ctx, start, count, fn) {
2927
+ for (let i = 0; i < count; i += 1) {
2928
+ for (const value of depBatch(ctx, start + i) ?? []) fn(value);
2416
2929
  }
2417
- return true;
2418
2930
  }
2419
- function freezeError(error) {
2420
- return Object.freeze({
2421
- ...error,
2422
- ...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) }
2423
- });
2931
+ function projectRuntimeFact(graph, runtime, name, factory, pick) {
2932
+ return graph.node(
2933
+ [runtime],
2934
+ (ctx) => {
2935
+ for (const fact of depBatch(ctx, 0) ?? []) {
2936
+ const typed = fact;
2937
+ const value = pick(typed);
2938
+ if (value !== void 0) ctx.down([["DATA", value]]);
2939
+ }
2940
+ },
2941
+ { name, factory }
2942
+ );
2424
2943
  }
2425
- function safeArrayLength(value) {
2426
- try {
2427
- return value.length;
2428
- } catch {
2429
- return void 0;
2944
+ function freezeCapabilityAdmissionViews(state) {
2945
+ return {
2946
+ admissionsByProposal: new Map(state.admissionsByProposal),
2947
+ admissionsBySubject: new Map(
2948
+ Array.from(state.admissionsBySubject, ([key, value]) => [key, Object.freeze([...value])])
2949
+ ),
2950
+ issues: Object.freeze([...state.issues]),
2951
+ audit: Object.freeze([...state.audit])
2952
+ };
2953
+ }
2954
+ function emptyCapabilityAdmissionState() {
2955
+ return {
2956
+ proposals: /* @__PURE__ */ new Map(),
2957
+ policies: /* @__PURE__ */ new Map(),
2958
+ decisions: /* @__PURE__ */ new Map(),
2959
+ admissionsById: /* @__PURE__ */ new Map(),
2960
+ admissionsByProposal: /* @__PURE__ */ new Map(),
2961
+ terminalDecisionIds: /* @__PURE__ */ new Set(),
2962
+ issueKeys: /* @__PURE__ */ new Set(),
2963
+ issueSeq: 0,
2964
+ statusSeq: 0,
2965
+ auditSeq: 0
2966
+ };
2967
+ }
2968
+ function dataIssue(code, message, opts = {}) {
2969
+ return {
2970
+ kind: "issue",
2971
+ code,
2972
+ message,
2973
+ severity: "error",
2974
+ subjectId: opts.subjectId,
2975
+ refs: opts.refs?.map((sourceRef) => `${sourceRef.kind}:${sourceRef.id}`),
2976
+ details: opts.details
2977
+ };
2978
+ }
2979
+ function uniqueSourceRefs(sourceRefs) {
2980
+ const seen = /* @__PURE__ */ new Set();
2981
+ const out = [];
2982
+ for (const sourceRef of sourceRefs) {
2983
+ const key = `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
2984
+ if (seen.has(key)) continue;
2985
+ seen.add(key);
2986
+ out.push(sourceRef);
2430
2987
  }
2988
+ return out;
2431
2989
  }
2432
- function errorMessage(error) {
2433
- return error instanceof Error ? error.message : String(error);
2990
+ function ref(kind, id) {
2991
+ return { kind, id };
2434
2992
  }
2435
2993
 
2436
2994
  export {
2995
+ agenticMemoryBundle,
2996
+ agenticMemoryConsolidationBundle,
2997
+ agenticMemoryContextPackingBundle,
2437
2998
  AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
2438
2999
  AGENTIC_MEMORY_RECORD_FRAME_VERSION,
2439
- agenticMemoryBundle,
2440
- agenticMemoryKgProjectionBundle,
2441
3000
  agenticMemoryRecordFrame,
2442
3001
  assertAgenticMemoryRecordFrame,
2443
3002
  agenticMemoryRecordFrameCodec,
2444
3003
  agenticMemoryRecordCodec,
3004
+ agenticMemoryKgProjectionBundle,
2445
3005
  agenticMemoryRetentionBundle,
2446
- agenticMemoryConsolidationBundle,
2447
- agenticMemoryContextPackingBundle
3006
+ capabilityAdmissionProposal,
3007
+ capabilityAdmissionProjector
2448
3008
  };
2449
- //# sourceMappingURL=chunk-COHO25CZ.js.map
3009
+ //# sourceMappingURL=chunk-4NWSNI4K.js.map