@namzu/sdk 0.1.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (626) hide show
  1. package/CHANGELOG.md +69 -2
  2. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  3. package/dist/agents/ReactiveAgent.js +5 -2
  4. package/dist/agents/ReactiveAgent.js.map +1 -1
  5. package/dist/agents/RouterAgent.d.ts.map +1 -1
  6. package/dist/agents/RouterAgent.js +3 -0
  7. package/dist/agents/RouterAgent.js.map +1 -1
  8. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  9. package/dist/agents/SupervisorAgent.js +21 -5
  10. package/dist/agents/SupervisorAgent.js.map +1 -1
  11. package/dist/bridge/a2a/index.d.ts +1 -1
  12. package/dist/bridge/a2a/index.d.ts.map +1 -1
  13. package/dist/bridge/a2a/index.js +1 -1
  14. package/dist/bridge/a2a/index.js.map +1 -1
  15. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  16. package/dist/bridge/a2a/mapper.js +6 -0
  17. package/dist/bridge/a2a/mapper.js.map +1 -1
  18. package/dist/bridge/a2a/message.d.ts +0 -2
  19. package/dist/bridge/a2a/message.d.ts.map +1 -1
  20. package/dist/bridge/a2a/message.js +0 -26
  21. package/dist/bridge/a2a/message.js.map +1 -1
  22. package/dist/bridge/a2a/task.d.ts +5 -4
  23. package/dist/bridge/a2a/task.d.ts.map +1 -1
  24. package/dist/bridge/a2a/task.js +4 -4
  25. package/dist/bridge/a2a/task.js.map +1 -1
  26. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  27. package/dist/bridge/sse/mapper.js +6 -0
  28. package/dist/bridge/sse/mapper.js.map +1 -1
  29. package/dist/constants/a2a/index.d.ts +2 -2
  30. package/dist/constants/a2a/index.d.ts.map +1 -1
  31. package/dist/constants/a2a/index.js.map +1 -1
  32. package/dist/contracts/api.d.ts +14 -27
  33. package/dist/contracts/api.d.ts.map +1 -1
  34. package/dist/contracts/ids.d.ts +1 -1
  35. package/dist/contracts/ids.d.ts.map +1 -1
  36. package/dist/contracts/index.d.ts +3 -3
  37. package/dist/contracts/index.d.ts.map +1 -1
  38. package/dist/contracts/index.js +1 -1
  39. package/dist/contracts/index.js.map +1 -1
  40. package/dist/contracts/schemas.d.ts +1 -31
  41. package/dist/contracts/schemas.d.ts.map +1 -1
  42. package/dist/contracts/schemas.js +1 -7
  43. package/dist/contracts/schemas.js.map +1 -1
  44. package/dist/gateway/local.d.ts.map +1 -1
  45. package/dist/gateway/local.js +6 -0
  46. package/dist/gateway/local.js.map +1 -1
  47. package/dist/index.d.ts +6 -3
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +6 -3
  50. package/dist/index.js.map +1 -1
  51. package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
  52. package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
  53. package/dist/manager/agent/__tests__/lifecycle.test.js +316 -0
  54. package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
  55. package/dist/manager/agent/lifecycle.d.ts +67 -3
  56. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  57. package/dist/manager/agent/lifecycle.js +375 -14
  58. package/dist/manager/agent/lifecycle.js.map +1 -1
  59. package/dist/manager/index.d.ts +2 -0
  60. package/dist/manager/index.d.ts.map +1 -1
  61. package/dist/manager/index.js +1 -0
  62. package/dist/manager/index.js.map +1 -1
  63. package/dist/manager/run/persistence.d.ts +10 -1
  64. package/dist/manager/run/persistence.d.ts.map +1 -1
  65. package/dist/manager/run/persistence.js +20 -0
  66. package/dist/manager/run/persistence.js.map +1 -1
  67. package/dist/manager/thread/__tests__/lifecycle.test.d.ts +2 -0
  68. package/dist/manager/thread/__tests__/lifecycle.test.d.ts.map +1 -0
  69. package/dist/manager/thread/__tests__/lifecycle.test.js +216 -0
  70. package/dist/manager/thread/__tests__/lifecycle.test.js.map +1 -0
  71. package/dist/manager/thread/lifecycle.d.ts +105 -0
  72. package/dist/manager/thread/lifecycle.d.ts.map +1 -0
  73. package/dist/manager/thread/lifecycle.js +186 -0
  74. package/dist/manager/thread/lifecycle.js.map +1 -0
  75. package/dist/rag/retriever.js +2 -2
  76. package/dist/run/reporter.d.ts.map +1 -1
  77. package/dist/run/reporter.js +25 -0
  78. package/dist/run/reporter.js.map +1 -1
  79. package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
  80. package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
  81. package/dist/runtime/query/__tests__/context.test.js +85 -0
  82. package/dist/runtime/query/__tests__/context.test.js.map +1 -0
  83. package/dist/runtime/query/context-cache.d.ts +3 -3
  84. package/dist/runtime/query/context-cache.d.ts.map +1 -1
  85. package/dist/runtime/query/context-cache.js +2 -2
  86. package/dist/runtime/query/context-cache.js.map +1 -1
  87. package/dist/runtime/query/context.d.ts +45 -1
  88. package/dist/runtime/query/context.d.ts.map +1 -1
  89. package/dist/runtime/query/context.js +50 -8
  90. package/dist/runtime/query/context.js.map +1 -1
  91. package/dist/runtime/query/events.d.ts.map +1 -1
  92. package/dist/runtime/query/events.js +8 -0
  93. package/dist/runtime/query/events.js.map +1 -1
  94. package/dist/runtime/query/index.d.ts +22 -1
  95. package/dist/runtime/query/index.d.ts.map +1 -1
  96. package/dist/runtime/query/index.js +11 -0
  97. package/dist/runtime/query/index.js.map +1 -1
  98. package/dist/session/__tests__/integration/_fixtures.d.ts +122 -0
  99. package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
  100. package/dist/session/__tests__/integration/_fixtures.js +215 -0
  101. package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
  102. package/dist/session/__tests__/integration/archive-gate.test.d.ts +15 -0
  103. package/dist/session/__tests__/integration/archive-gate.test.d.ts.map +1 -0
  104. package/dist/session/__tests__/integration/archive-gate.test.js +214 -0
  105. package/dist/session/__tests__/integration/archive-gate.test.js.map +1 -0
  106. package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
  107. package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
  108. package/dist/session/__tests__/integration/capacity-caps.test.js +123 -0
  109. package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
  110. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
  111. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
  112. package/dist/session/__tests__/integration/e2e-spawn.test.js +238 -0
  113. package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
  114. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
  115. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
  116. package/dist/session/__tests__/integration/event-stream-ordering.test.js +330 -0
  117. package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
  118. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
  119. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
  120. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +182 -0
  121. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
  122. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
  123. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
  124. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +156 -0
  125. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
  126. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
  127. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
  128. package/dist/session/__tests__/integration/handoff-single-e2e.test.js +179 -0
  129. package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
  130. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
  131. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
  132. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +158 -0
  133. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
  134. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
  135. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
  136. package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
  137. package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
  138. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
  139. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
  140. package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
  141. package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
  142. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
  143. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
  144. package/dist/session/__tests__/integration/prev-artifact-dag.test.js +242 -0
  145. package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
  146. package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
  147. package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
  148. package/dist/session/__tests__/integration/retention-archive.test.js +187 -0
  149. package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
  150. package/dist/session/__tests__/integration/spawn-rollback.test.d.ts +26 -0
  151. package/dist/session/__tests__/integration/spawn-rollback.test.d.ts.map +1 -0
  152. package/dist/session/__tests__/integration/spawn-rollback.test.js +236 -0
  153. package/dist/session/__tests__/integration/spawn-rollback.test.js.map +1 -0
  154. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
  155. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
  156. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +201 -0
  157. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
  158. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
  159. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
  160. package/dist/session/__tests__/integration/tenant-isolation.test.js +189 -0
  161. package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
  162. package/dist/session/errors.d.ts +139 -0
  163. package/dist/session/errors.d.ts.map +1 -0
  164. package/dist/session/errors.js +107 -0
  165. package/dist/session/errors.js.map +1 -0
  166. package/dist/session/events/index.d.ts +4 -0
  167. package/dist/session/events/index.d.ts.map +1 -0
  168. package/dist/session/events/index.js +8 -0
  169. package/dist/session/events/index.js.map +1 -0
  170. package/dist/session/events/schema-version.d.ts +13 -0
  171. package/dist/session/events/schema-version.d.ts.map +1 -0
  172. package/dist/session/events/schema-version.js +12 -0
  173. package/dist/session/events/schema-version.js.map +1 -0
  174. package/dist/session/events/types.d.ts +64 -0
  175. package/dist/session/events/types.d.ts.map +1 -0
  176. package/dist/session/events/types.js +2 -0
  177. package/dist/session/events/types.js.map +1 -0
  178. package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
  179. package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
  180. package/dist/session/handoff/__tests__/broadcast.test.js +261 -0
  181. package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
  182. package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
  183. package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
  184. package/dist/session/handoff/__tests__/capacity.test.js +103 -0
  185. package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
  186. package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
  187. package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
  188. package/dist/session/handoff/__tests__/single.test.js +239 -0
  189. package/dist/session/handoff/__tests__/single.test.js.map +1 -0
  190. package/dist/session/handoff/assignment.d.ts +71 -0
  191. package/dist/session/handoff/assignment.d.ts.map +1 -0
  192. package/dist/session/handoff/assignment.js +11 -0
  193. package/dist/session/handoff/assignment.js.map +1 -0
  194. package/dist/session/handoff/broadcast.d.ts +54 -0
  195. package/dist/session/handoff/broadcast.d.ts.map +1 -0
  196. package/dist/session/handoff/broadcast.js +311 -0
  197. package/dist/session/handoff/broadcast.js.map +1 -0
  198. package/dist/session/handoff/capacity.d.ts +66 -0
  199. package/dist/session/handoff/capacity.d.ts.map +1 -0
  200. package/dist/session/handoff/capacity.js +60 -0
  201. package/dist/session/handoff/capacity.js.map +1 -0
  202. package/dist/session/handoff/events.d.ts +66 -0
  203. package/dist/session/handoff/events.d.ts.map +1 -0
  204. package/dist/session/handoff/events.js +13 -0
  205. package/dist/session/handoff/events.js.map +1 -0
  206. package/dist/session/handoff/index.d.ts +12 -0
  207. package/dist/session/handoff/index.d.ts.map +1 -0
  208. package/dist/session/handoff/index.js +9 -0
  209. package/dist/session/handoff/index.js.map +1 -0
  210. package/dist/session/handoff/single.d.ts +69 -0
  211. package/dist/session/handoff/single.d.ts.map +1 -0
  212. package/dist/session/handoff/single.js +229 -0
  213. package/dist/session/handoff/single.js.map +1 -0
  214. package/dist/session/handoff/version.d.ts +52 -0
  215. package/dist/session/handoff/version.d.ts.map +1 -0
  216. package/dist/session/handoff/version.js +36 -0
  217. package/dist/session/handoff/version.js.map +1 -0
  218. package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
  219. package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
  220. package/dist/session/hierarchy/__tests__/session.test.js +69 -0
  221. package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
  222. package/dist/session/hierarchy/actor.d.ts +26 -0
  223. package/dist/session/hierarchy/actor.d.ts.map +1 -0
  224. package/dist/session/hierarchy/actor.js +2 -0
  225. package/dist/session/hierarchy/actor.js.map +1 -0
  226. package/dist/session/hierarchy/index.d.ts +9 -0
  227. package/dist/session/hierarchy/index.d.ts.map +1 -0
  228. package/dist/session/hierarchy/index.js +4 -0
  229. package/dist/session/hierarchy/index.js.map +1 -0
  230. package/dist/session/hierarchy/lineage.d.ts +15 -0
  231. package/dist/session/hierarchy/lineage.d.ts.map +1 -0
  232. package/dist/session/hierarchy/lineage.js +2 -0
  233. package/dist/session/hierarchy/lineage.js.map +1 -0
  234. package/dist/session/hierarchy/project.d.ts +40 -0
  235. package/dist/session/hierarchy/project.d.ts.map +1 -0
  236. package/dist/session/hierarchy/project.js +2 -0
  237. package/dist/session/hierarchy/project.js.map +1 -0
  238. package/dist/session/hierarchy/session.d.ts +71 -0
  239. package/dist/session/hierarchy/session.d.ts.map +1 -0
  240. package/dist/session/hierarchy/session.js +51 -0
  241. package/dist/session/hierarchy/session.js.map +1 -0
  242. package/dist/session/hierarchy/sub-session.d.ts +76 -0
  243. package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
  244. package/dist/session/hierarchy/sub-session.js +2 -0
  245. package/dist/session/hierarchy/sub-session.js.map +1 -0
  246. package/dist/session/hierarchy/tenant.d.ts +13 -0
  247. package/dist/session/hierarchy/tenant.d.ts.map +1 -0
  248. package/dist/session/hierarchy/tenant.js +2 -0
  249. package/dist/session/hierarchy/tenant.js.map +1 -0
  250. package/dist/session/hierarchy/thread.d.ts +54 -0
  251. package/dist/session/hierarchy/thread.d.ts.map +1 -0
  252. package/dist/session/hierarchy/thread.js +2 -0
  253. package/dist/session/hierarchy/thread.js.map +1 -0
  254. package/dist/session/index.d.ts +10 -0
  255. package/dist/session/index.d.ts.map +1 -0
  256. package/dist/session/index.js +15 -0
  257. package/dist/session/index.js.map +1 -0
  258. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
  259. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
  260. package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
  261. package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
  262. package/dist/session/intervention/index.d.ts +3 -0
  263. package/dist/session/intervention/index.d.ts.map +1 -0
  264. package/dist/session/intervention/index.js +8 -0
  265. package/dist/session/intervention/index.js.map +1 -0
  266. package/dist/session/intervention/prev-artifact.d.ts +103 -0
  267. package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
  268. package/dist/session/intervention/prev-artifact.js +112 -0
  269. package/dist/session/intervention/prev-artifact.js.map +1 -0
  270. package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
  271. package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
  272. package/dist/session/migration/__tests__/filesystem.test.js +188 -0
  273. package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
  274. package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
  275. package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
  276. package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
  277. package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
  278. package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
  279. package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
  280. package/dist/session/migration/__tests__/marker.test.js +75 -0
  281. package/dist/session/migration/__tests__/marker.test.js.map +1 -0
  282. package/dist/session/migration/errors.d.ts +26 -0
  283. package/dist/session/migration/errors.d.ts.map +1 -0
  284. package/dist/session/migration/errors.js +22 -0
  285. package/dist/session/migration/errors.js.map +1 -0
  286. package/dist/session/migration/filesystem.d.ts +94 -0
  287. package/dist/session/migration/filesystem.d.ts.map +1 -0
  288. package/dist/session/migration/filesystem.js +319 -0
  289. package/dist/session/migration/filesystem.js.map +1 -0
  290. package/dist/session/migration/id-prefix.d.ts +93 -0
  291. package/dist/session/migration/id-prefix.d.ts.map +1 -0
  292. package/dist/session/migration/id-prefix.js +111 -0
  293. package/dist/session/migration/id-prefix.js.map +1 -0
  294. package/dist/session/migration/index.d.ts +8 -0
  295. package/dist/session/migration/index.d.ts.map +1 -0
  296. package/dist/session/migration/index.js +8 -0
  297. package/dist/session/migration/index.js.map +1 -0
  298. package/dist/session/migration/marker.d.ts +57 -0
  299. package/dist/session/migration/marker.d.ts.map +1 -0
  300. package/dist/session/migration/marker.js +111 -0
  301. package/dist/session/migration/marker.js.map +1 -0
  302. package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
  303. package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
  304. package/dist/session/retention/__tests__/archive.test.js +253 -0
  305. package/dist/session/retention/__tests__/archive.test.js.map +1 -0
  306. package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
  307. package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
  308. package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
  309. package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
  310. package/dist/session/retention/archive-backend-ref.d.ts +18 -0
  311. package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
  312. package/dist/session/retention/archive-backend-ref.js +2 -0
  313. package/dist/session/retention/archive-backend-ref.js.map +1 -0
  314. package/dist/session/retention/archive.d.ts +130 -0
  315. package/dist/session/retention/archive.d.ts.map +1 -0
  316. package/dist/session/retention/archive.js +203 -0
  317. package/dist/session/retention/archive.js.map +1 -0
  318. package/dist/session/retention/backend.d.ts +101 -0
  319. package/dist/session/retention/backend.d.ts.map +1 -0
  320. package/dist/session/retention/backend.js +15 -0
  321. package/dist/session/retention/backend.js.map +1 -0
  322. package/dist/session/retention/disk-backend.d.ts +59 -0
  323. package/dist/session/retention/disk-backend.d.ts.map +1 -0
  324. package/dist/session/retention/disk-backend.js +236 -0
  325. package/dist/session/retention/disk-backend.js.map +1 -0
  326. package/dist/session/retention/index.d.ts +9 -0
  327. package/dist/session/retention/index.d.ts.map +1 -0
  328. package/dist/session/retention/index.js +6 -0
  329. package/dist/session/retention/index.js.map +1 -0
  330. package/dist/session/retention/policy.d.ts +49 -0
  331. package/dist/session/retention/policy.d.ts.map +1 -0
  332. package/dist/session/retention/policy.js +21 -0
  333. package/dist/session/retention/policy.js.map +1 -0
  334. package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
  335. package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
  336. package/dist/session/summary/__tests__/materialize.test.js +270 -0
  337. package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
  338. package/dist/session/summary/deliverable.d.ts +74 -0
  339. package/dist/session/summary/deliverable.d.ts.map +1 -0
  340. package/dist/session/summary/deliverable.js +20 -0
  341. package/dist/session/summary/deliverable.js.map +1 -0
  342. package/dist/session/summary/index.d.ts +6 -0
  343. package/dist/session/summary/index.d.ts.map +1 -0
  344. package/dist/session/summary/index.js +9 -0
  345. package/dist/session/summary/index.js.map +1 -0
  346. package/dist/session/summary/materialize.d.ts +82 -0
  347. package/dist/session/summary/materialize.d.ts.map +1 -0
  348. package/dist/session/summary/materialize.js +117 -0
  349. package/dist/session/summary/materialize.js.map +1 -0
  350. package/dist/session/summary/ref.d.ts +91 -0
  351. package/dist/session/summary/ref.d.ts.map +1 -0
  352. package/dist/session/summary/ref.js +51 -0
  353. package/dist/session/summary/ref.js.map +1 -0
  354. package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
  355. package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
  356. package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
  357. package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
  358. package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
  359. package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
  360. package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
  361. package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
  362. package/dist/session/workspace/driver.d.ts +55 -0
  363. package/dist/session/workspace/driver.d.ts.map +1 -0
  364. package/dist/session/workspace/driver.js +12 -0
  365. package/dist/session/workspace/driver.js.map +1 -0
  366. package/dist/session/workspace/git-worktree.d.ts +65 -0
  367. package/dist/session/workspace/git-worktree.d.ts.map +1 -0
  368. package/dist/session/workspace/git-worktree.js +156 -0
  369. package/dist/session/workspace/git-worktree.js.map +1 -0
  370. package/dist/session/workspace/index.d.ts +8 -0
  371. package/dist/session/workspace/index.d.ts.map +1 -0
  372. package/dist/session/workspace/index.js +7 -0
  373. package/dist/session/workspace/index.js.map +1 -0
  374. package/dist/session/workspace/path-builder.d.ts +50 -0
  375. package/dist/session/workspace/path-builder.d.ts.map +1 -0
  376. package/dist/session/workspace/path-builder.js +50 -0
  377. package/dist/session/workspace/path-builder.js.map +1 -0
  378. package/dist/session/workspace/ref.d.ts +46 -0
  379. package/dist/session/workspace/ref.d.ts.map +1 -0
  380. package/dist/session/workspace/ref.js +11 -0
  381. package/dist/session/workspace/ref.js.map +1 -0
  382. package/dist/session/workspace/registry.d.ts +26 -0
  383. package/dist/session/workspace/registry.d.ts.map +1 -0
  384. package/dist/session/workspace/registry.js +35 -0
  385. package/dist/session/workspace/registry.js.map +1 -0
  386. package/dist/store/index.d.ts +0 -2
  387. package/dist/store/index.d.ts.map +1 -1
  388. package/dist/store/index.js +0 -1
  389. package/dist/store/index.js.map +1 -1
  390. package/dist/store/session/__tests__/disk.test.d.ts +2 -0
  391. package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
  392. package/dist/store/session/__tests__/disk.test.js +267 -0
  393. package/dist/store/session/__tests__/disk.test.js.map +1 -0
  394. package/dist/store/session/__tests__/memory.test.d.ts +2 -0
  395. package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
  396. package/dist/store/session/__tests__/memory.test.js +258 -0
  397. package/dist/store/session/__tests__/memory.test.js.map +1 -0
  398. package/dist/store/session/disk.d.ts +86 -0
  399. package/dist/store/session/disk.d.ts.map +1 -0
  400. package/dist/store/session/disk.js +818 -0
  401. package/dist/store/session/disk.js.map +1 -0
  402. package/dist/store/session/index.d.ts +7 -0
  403. package/dist/store/session/index.d.ts.map +1 -0
  404. package/dist/store/session/index.js +10 -0
  405. package/dist/store/session/index.js.map +1 -0
  406. package/dist/store/session/linkage.d.ts +38 -0
  407. package/dist/store/session/linkage.d.ts.map +1 -0
  408. package/dist/store/session/linkage.js +64 -0
  409. package/dist/store/session/linkage.js.map +1 -0
  410. package/dist/store/session/memory.d.ts +49 -0
  411. package/dist/store/session/memory.d.ts.map +1 -0
  412. package/dist/store/session/memory.js +335 -0
  413. package/dist/store/session/memory.js.map +1 -0
  414. package/dist/store/session/messages.d.ts +20 -0
  415. package/dist/store/session/messages.d.ts.map +1 -0
  416. package/dist/store/session/messages.js +12 -0
  417. package/dist/store/session/messages.js.map +1 -0
  418. package/dist/store/thread/disk.d.ts +41 -0
  419. package/dist/store/thread/disk.d.ts.map +1 -0
  420. package/dist/store/thread/disk.js +229 -0
  421. package/dist/store/thread/disk.js.map +1 -0
  422. package/dist/store/thread/index.d.ts +4 -0
  423. package/dist/store/thread/index.d.ts.map +1 -0
  424. package/dist/store/thread/index.js +6 -0
  425. package/dist/store/thread/index.js.map +1 -0
  426. package/dist/store/thread/memory.d.ts +23 -0
  427. package/dist/store/thread/memory.d.ts.map +1 -0
  428. package/dist/store/thread/memory.js +90 -0
  429. package/dist/store/thread/memory.js.map +1 -0
  430. package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
  431. package/dist/types/agent/base.d.ts +24 -1
  432. package/dist/types/agent/base.d.ts.map +1 -1
  433. package/dist/types/agent/factory.d.ts +8 -2
  434. package/dist/types/agent/factory.d.ts.map +1 -1
  435. package/dist/types/agent/task.d.ts +57 -2
  436. package/dist/types/agent/task.d.ts.map +1 -1
  437. package/dist/types/agent/task.js.map +1 -1
  438. package/dist/types/ids/index.d.ts +22 -3
  439. package/dist/types/ids/index.d.ts.map +1 -1
  440. package/dist/types/ids/index.js +8 -1
  441. package/dist/types/ids/index.js.map +1 -1
  442. package/dist/types/invocation/__tests__/state.test.js +36 -29
  443. package/dist/types/invocation/__tests__/state.test.js.map +1 -1
  444. package/dist/types/invocation/index.d.ts +20 -4
  445. package/dist/types/invocation/index.d.ts.map +1 -1
  446. package/dist/types/invocation/index.js +10 -7
  447. package/dist/types/invocation/index.js.map +1 -1
  448. package/dist/types/rag/retrieval.d.ts +4 -3
  449. package/dist/types/rag/retrieval.d.ts.map +1 -1
  450. package/dist/types/run/config.d.ts +12 -1
  451. package/dist/types/run/config.d.ts.map +1 -1
  452. package/dist/types/run/events.d.ts +26 -1
  453. package/dist/types/run/events.d.ts.map +1 -1
  454. package/dist/types/run/index.d.ts.map +1 -1
  455. package/dist/types/run/index.js +8 -0
  456. package/dist/types/run/index.js.map +1 -1
  457. package/dist/types/run/metadata.d.ts +12 -2
  458. package/dist/types/run/metadata.d.ts.map +1 -1
  459. package/dist/types/run/status.d.ts +26 -0
  460. package/dist/types/run/status.d.ts.map +1 -0
  461. package/dist/types/run/status.js +2 -0
  462. package/dist/types/run/status.js.map +1 -0
  463. package/dist/types/session/ids.d.ts +9 -0
  464. package/dist/types/session/ids.d.ts.map +1 -0
  465. package/dist/types/session/ids.js +9 -0
  466. package/dist/types/session/ids.js.map +1 -0
  467. package/dist/types/session/index.d.ts +3 -0
  468. package/dist/types/session/index.d.ts.map +1 -0
  469. package/dist/types/session/index.js +5 -0
  470. package/dist/types/session/index.js.map +1 -0
  471. package/dist/types/session/store.d.ts +210 -0
  472. package/dist/types/session/store.d.ts.map +1 -0
  473. package/dist/types/session/store.js +9 -0
  474. package/dist/types/session/store.js.map +1 -0
  475. package/dist/types/thread/index.d.ts +2 -0
  476. package/dist/types/thread/index.d.ts.map +1 -0
  477. package/dist/types/thread/index.js +5 -0
  478. package/dist/types/thread/index.js.map +1 -0
  479. package/dist/types/thread/store.d.ts +86 -0
  480. package/dist/types/thread/store.d.ts.map +1 -0
  481. package/dist/types/thread/store.js +22 -0
  482. package/dist/types/thread/store.js.map +1 -0
  483. package/dist/utils/id.d.ts +8 -2
  484. package/dist/utils/id.d.ts.map +1 -1
  485. package/dist/utils/id.js +22 -4
  486. package/dist/utils/id.js.map +1 -1
  487. package/package.json +6 -11
  488. package/src/agents/ReactiveAgent.ts +7 -2
  489. package/src/agents/RouterAgent.ts +5 -0
  490. package/src/agents/SupervisorAgent.ts +29 -6
  491. package/src/bridge/a2a/index.ts +0 -1
  492. package/src/bridge/a2a/mapper.ts +7 -0
  493. package/src/bridge/a2a/message.ts +0 -32
  494. package/src/bridge/a2a/task.ts +9 -8
  495. package/src/bridge/sse/mapper.ts +8 -1
  496. package/src/constants/a2a/index.ts +2 -2
  497. package/src/contracts/api.ts +14 -30
  498. package/src/contracts/ids.ts +1 -1
  499. package/src/contracts/index.ts +3 -7
  500. package/src/contracts/schemas.ts +1 -8
  501. package/src/gateway/local.ts +6 -0
  502. package/src/index.ts +14 -4
  503. package/src/manager/agent/__tests__/lifecycle.test.ts +473 -0
  504. package/src/manager/agent/lifecycle.ts +515 -21
  505. package/src/manager/index.ts +3 -0
  506. package/src/manager/run/persistence.ts +26 -1
  507. package/src/manager/thread/__tests__/lifecycle.test.ts +286 -0
  508. package/src/manager/thread/lifecycle.ts +217 -0
  509. package/src/rag/retriever.ts +2 -2
  510. package/src/run/reporter.ts +28 -0
  511. package/src/runtime/query/__tests__/context.test.ts +102 -0
  512. package/src/runtime/query/context-cache.ts +4 -4
  513. package/src/runtime/query/context.ts +98 -9
  514. package/src/runtime/query/events.ts +8 -0
  515. package/src/runtime/query/index.ts +38 -1
  516. package/src/session/__tests__/integration/_fixtures.ts +310 -0
  517. package/src/session/__tests__/integration/archive-gate.test.ts +288 -0
  518. package/src/session/__tests__/integration/capacity-caps.test.ts +171 -0
  519. package/src/session/__tests__/integration/e2e-spawn.test.ts +296 -0
  520. package/src/session/__tests__/integration/event-stream-ordering.test.ts +410 -0
  521. package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +271 -0
  522. package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +214 -0
  523. package/src/session/__tests__/integration/handoff-single-e2e.test.ts +251 -0
  524. package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +240 -0
  525. package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
  526. package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
  527. package/src/session/__tests__/integration/prev-artifact-dag.test.ts +325 -0
  528. package/src/session/__tests__/integration/retention-archive.test.ts +233 -0
  529. package/src/session/__tests__/integration/spawn-rollback.test.ts +313 -0
  530. package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +239 -0
  531. package/src/session/__tests__/integration/tenant-isolation.test.ts +292 -0
  532. package/src/session/errors.ts +159 -0
  533. package/src/session/events/index.ts +16 -0
  534. package/src/session/events/schema-version.ts +13 -0
  535. package/src/session/events/types.ts +71 -0
  536. package/src/session/handoff/__tests__/broadcast.test.ts +378 -0
  537. package/src/session/handoff/__tests__/capacity.test.ts +129 -0
  538. package/src/session/handoff/__tests__/single.test.ts +333 -0
  539. package/src/session/handoff/assignment.ts +74 -0
  540. package/src/session/handoff/broadcast.ts +406 -0
  541. package/src/session/handoff/capacity.ts +121 -0
  542. package/src/session/handoff/events.ts +72 -0
  543. package/src/session/handoff/index.ts +29 -0
  544. package/src/session/handoff/single.ts +310 -0
  545. package/src/session/handoff/version.ts +59 -0
  546. package/src/session/hierarchy/__tests__/session.test.ts +100 -0
  547. package/src/session/hierarchy/actor.ts +17 -0
  548. package/src/session/hierarchy/index.ts +18 -0
  549. package/src/session/hierarchy/lineage.ts +15 -0
  550. package/src/session/hierarchy/project.ts +41 -0
  551. package/src/session/hierarchy/session.ts +109 -0
  552. package/src/session/hierarchy/sub-session.ts +92 -0
  553. package/src/session/hierarchy/tenant.ts +13 -0
  554. package/src/session/hierarchy/thread.ts +55 -0
  555. package/src/session/index.ts +15 -0
  556. package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
  557. package/src/session/intervention/index.ts +16 -0
  558. package/src/session/intervention/prev-artifact.ts +180 -0
  559. package/src/session/migration/__tests__/filesystem.test.ts +263 -0
  560. package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
  561. package/src/session/migration/__tests__/marker.test.ts +84 -0
  562. package/src/session/migration/errors.ts +23 -0
  563. package/src/session/migration/filesystem.ts +401 -0
  564. package/src/session/migration/id-prefix.ts +141 -0
  565. package/src/session/migration/index.ts +38 -0
  566. package/src/session/migration/marker.ts +131 -0
  567. package/src/session/retention/__tests__/archive.test.ts +318 -0
  568. package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
  569. package/src/session/retention/archive-backend-ref.ts +17 -0
  570. package/src/session/retention/archive.ts +281 -0
  571. package/src/session/retention/backend.ts +107 -0
  572. package/src/session/retention/disk-backend.ts +304 -0
  573. package/src/session/retention/index.ts +16 -0
  574. package/src/session/retention/policy.ts +53 -0
  575. package/src/session/summary/__tests__/materialize.test.ts +343 -0
  576. package/src/session/summary/deliverable.ts +84 -0
  577. package/src/session/summary/index.ts +31 -0
  578. package/src/session/summary/materialize.ts +169 -0
  579. package/src/session/summary/ref.ts +104 -0
  580. package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
  581. package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
  582. package/src/session/workspace/driver.ts +60 -0
  583. package/src/session/workspace/git-worktree.ts +209 -0
  584. package/src/session/workspace/index.ts +25 -0
  585. package/src/session/workspace/path-builder.ts +71 -0
  586. package/src/session/workspace/ref.ts +50 -0
  587. package/src/session/workspace/registry.ts +42 -0
  588. package/src/store/index.ts +0 -3
  589. package/src/store/session/__tests__/disk.test.ts +397 -0
  590. package/src/store/session/__tests__/memory.test.ts +402 -0
  591. package/src/store/session/disk.ts +976 -0
  592. package/src/store/session/index.ts +13 -0
  593. package/src/store/session/linkage.ts +80 -0
  594. package/src/store/session/memory.ts +412 -0
  595. package/src/store/session/messages.ts +21 -0
  596. package/src/store/thread/disk.ts +261 -0
  597. package/src/store/thread/index.ts +7 -0
  598. package/src/store/thread/memory.ts +104 -0
  599. package/src/types/agent/base.ts +27 -1
  600. package/src/types/agent/factory.ts +8 -3
  601. package/src/types/agent/task.ts +66 -2
  602. package/src/types/ids/index.ts +34 -3
  603. package/src/types/invocation/__tests__/state.test.ts +37 -29
  604. package/src/types/invocation/index.ts +26 -10
  605. package/src/types/rag/retrieval.ts +4 -3
  606. package/src/types/run/config.ts +13 -1
  607. package/src/types/run/events.ts +36 -1
  608. package/src/types/run/index.ts +8 -0
  609. package/src/types/run/metadata.ts +12 -2
  610. package/src/types/run/status.ts +33 -0
  611. package/src/types/session/ids.ts +23 -0
  612. package/src/types/session/index.ts +27 -0
  613. package/src/types/session/store.ts +252 -0
  614. package/src/types/thread/index.ts +5 -0
  615. package/src/types/thread/store.ts +92 -0
  616. package/src/utils/id.ts +34 -4
  617. package/dist/store/conversation/memory.d.ts +0 -21
  618. package/dist/store/conversation/memory.d.ts.map +0 -1
  619. package/dist/store/conversation/memory.js +0 -86
  620. package/dist/store/conversation/memory.js.map +0 -1
  621. package/dist/types/conversation/index.d.ts +0 -7
  622. package/dist/types/conversation/index.d.ts.map +0 -1
  623. package/dist/types/conversation/index.js +0 -2
  624. package/dist/types/conversation/index.js.map +0 -1
  625. package/src/store/conversation/memory.ts +0 -121
  626. package/src/types/conversation/index.ts +0 -8
@@ -0,0 +1,410 @@
1
+ /**
2
+ * Integration — event stream ordering + lineage + schemaVersion envelope.
3
+ *
4
+ * Covers roadmap §5 invariants:
5
+ * - §10.1 schemaVersion: 2 on every sub-session RunEvent
6
+ * - §10.3 tree-scoped monotonic ordering by (rootSessionId, eventId)
7
+ * - §10.3 depth filter ('self' vs 'tree') at subscribe time
8
+ * - §10.4 lineage stamped on every sub-session event with parent + root + depth
9
+ *
10
+ * Orthogonal to `e2e-spawn.test.ts` (covers single-level spawn). This file
11
+ * drives a multi-level (3-deep) delegation tree so monotonic ordering across
12
+ * concurrent descendants is observable.
13
+ */
14
+
15
+ import { describe, expect, it } from 'vitest'
16
+ import { EMPTY_TOKEN_USAGE } from '../../../constants/limits.js'
17
+ import type { AgentManager } from '../../../manager/agent/lifecycle.js'
18
+ import type { AgentInput, BaseAgentConfig, BaseAgentResult } from '../../../types/agent/base.js'
19
+ import type { RunId } from '../../../types/ids/index.js'
20
+ import { createAssistantMessage } from '../../../types/message/index.js'
21
+ import type { RunEvent } from '../../../types/run/events.js'
22
+ import { ZERO_COST } from '../../../utils/cost.js'
23
+ import {
24
+ DEFAULT_TENANT,
25
+ buildAgent,
26
+ buildAgentCustom,
27
+ buildDefinition,
28
+ buildHarness,
29
+ buildSendMessageOptions,
30
+ buildTaskContext,
31
+ seedActiveParent,
32
+ } from './_fixtures.js'
33
+
34
+ describe('Integration — event stream ordering + lineage + schemaVersion', () => {
35
+ it('every sub-session RunEvent carries schemaVersion: 2', async () => {
36
+ const harness = buildHarness()
37
+ const { project, thread, session, actor } = await seedActiveParent(harness)
38
+ harness.registry.register(buildDefinition(buildAgent('worker')))
39
+
40
+ const captured: RunEvent[] = []
41
+ const task = await harness.manager.sendMessage(
42
+ buildSendMessageOptions({
43
+ agentId: 'worker',
44
+ parentSessionId: session.id,
45
+ projectId: project.id,
46
+ tenantId: DEFAULT_TENANT,
47
+ parentActor: actor,
48
+ }),
49
+ buildTaskContext({
50
+ sessionId: session.id,
51
+ projectId: project.id,
52
+ threadId: thread.id,
53
+ tenantId: DEFAULT_TENANT,
54
+ parentActor: actor,
55
+ }),
56
+ (ev) => {
57
+ captured.push(ev)
58
+ },
59
+ )
60
+ await harness.manager.waitForCompletion(task.taskId)
61
+
62
+ // Every sub-session lifecycle event is stamped with schemaVersion: 2.
63
+ const subSessionEvents = captured.filter(
64
+ (e) =>
65
+ e.type === 'subsession_spawned' ||
66
+ e.type === 'subsession_messaged' ||
67
+ e.type === 'subsession_idled',
68
+ )
69
+ expect(subSessionEvents.length).toBeGreaterThan(0)
70
+ for (const ev of subSessionEvents) {
71
+ expect(ev.schemaVersion).toBe(2)
72
+ }
73
+ })
74
+
75
+ it('every sub-session event carries lineage { parentSessionId, rootSessionId, depth }', async () => {
76
+ const harness = buildHarness()
77
+ const { project, thread, session, actor } = await seedActiveParent(harness)
78
+ harness.registry.register(buildDefinition(buildAgent('worker')))
79
+
80
+ const captured: RunEvent[] = []
81
+ const task = await harness.manager.sendMessage(
82
+ buildSendMessageOptions({
83
+ agentId: 'worker',
84
+ parentSessionId: session.id,
85
+ projectId: project.id,
86
+ tenantId: DEFAULT_TENANT,
87
+ parentActor: actor,
88
+ }),
89
+ buildTaskContext({
90
+ sessionId: session.id,
91
+ projectId: project.id,
92
+ threadId: thread.id,
93
+ tenantId: DEFAULT_TENANT,
94
+ parentActor: actor,
95
+ }),
96
+ (ev) => {
97
+ captured.push(ev)
98
+ },
99
+ )
100
+ await harness.manager.waitForCompletion(task.taskId)
101
+
102
+ const spawned = captured.find((e) => e.type === 'subsession_spawned')
103
+ const idled = captured.find((e) => e.type === 'subsession_idled')
104
+ expect(spawned).toBeDefined()
105
+ expect(idled).toBeDefined()
106
+
107
+ if (spawned && 'lineage' in spawned) {
108
+ expect(spawned.lineage.parentSessionId).toBe(session.id)
109
+ expect(spawned.lineage.rootSessionId).toBe(session.id)
110
+ expect(spawned.lineage.depth).toBe(1)
111
+ }
112
+ if (idled && 'lineage' in idled) {
113
+ expect(idled.lineage.parentSessionId).toBe(session.id)
114
+ expect(idled.lineage.rootSessionId).toBe(session.id)
115
+ expect(idled.lineage.depth).toBe(1)
116
+ }
117
+ })
118
+
119
+ it('3-deep delegation: rootSessionId identical across tree; depth ascends 1→2→3', async () => {
120
+ const harness = buildHarness()
121
+ const { project, thread, session, actor } = await seedActiveParent(harness)
122
+
123
+ // Wire a cascading agent: level-1 child spawns level-2 via its own
124
+ // sendMessage. We hand a reference to the manager into the child agent
125
+ // via a closure so level-2 can spawn level-3.
126
+ const manager: AgentManager = harness.manager
127
+ const nestedEventsCaptured: RunEvent[] = []
128
+
129
+ const leafAgent = buildAgent('leaf', 'leaf result')
130
+ const midAgent = buildAgentCustom(
131
+ 'mid',
132
+ async (_input: AgentInput, config: BaseAgentConfig): Promise<BaseAgentResult> => {
133
+ // Spawn a level-2 child from inside the mid-agent's run.
134
+ if (!config.sessionId || !config.threadId || !config.projectId || !config.tenantId) {
135
+ throw new Error('mid agent missing session scoping')
136
+ }
137
+ // Flip child session to active so it is a legal spawn parent.
138
+ const childSessionId = config.sessionId
139
+ const cs = await harness.store.getSession(childSessionId, config.tenantId)
140
+ if (cs && cs.status !== 'active') {
141
+ await harness.store.updateSession({ ...cs, status: 'active' }, config.tenantId)
142
+ }
143
+ const task2 = await manager.sendMessage(
144
+ {
145
+ agentId: 'leaf',
146
+ input: { messages: [], workingDirectory: '/tmp' },
147
+ parentSessionId: childSessionId,
148
+ tenantId: config.tenantId,
149
+ projectId: config.projectId,
150
+ parentActor: { kind: 'agent', agentId: 'mid' as never, tenantId: config.tenantId },
151
+ },
152
+ {
153
+ parentRunId: 'run_mid' as RunId,
154
+ parentAgentId: 'mid',
155
+ parentAbortController: new AbortController(),
156
+ depth: 1,
157
+ budgetTracker: { total: 10_000, remaining: 10_000 },
158
+ tenantId: config.tenantId,
159
+ threadId: config.threadId,
160
+ sessionId: childSessionId,
161
+ projectId: config.projectId,
162
+ parentActor: { kind: 'agent', agentId: 'mid' as never, tenantId: config.tenantId },
163
+ },
164
+ (ev) => {
165
+ nestedEventsCaptured.push(ev)
166
+ },
167
+ )
168
+ await manager.waitForCompletion(task2.taskId)
169
+
170
+ return {
171
+ runId: 'run_mid_result' as RunId,
172
+ status: 'completed',
173
+ usage: { ...EMPTY_TOKEN_USAGE },
174
+ cost: { ...ZERO_COST },
175
+ iterations: 1,
176
+ durationMs: 1,
177
+ messages: [createAssistantMessage('mid done')],
178
+ result: 'mid done',
179
+ }
180
+ },
181
+ )
182
+
183
+ harness.registry.register(buildDefinition(leafAgent))
184
+ harness.registry.register(buildDefinition(midAgent))
185
+
186
+ const outerCaptured: RunEvent[] = []
187
+ const task = await harness.manager.sendMessage(
188
+ buildSendMessageOptions({
189
+ agentId: 'mid',
190
+ parentSessionId: session.id,
191
+ projectId: project.id,
192
+ tenantId: DEFAULT_TENANT,
193
+ parentActor: actor,
194
+ }),
195
+ buildTaskContext({
196
+ sessionId: session.id,
197
+ projectId: project.id,
198
+ threadId: thread.id,
199
+ tenantId: DEFAULT_TENANT,
200
+ parentActor: actor,
201
+ }),
202
+ (ev) => {
203
+ outerCaptured.push(ev)
204
+ },
205
+ )
206
+ await harness.manager.waitForCompletion(task.taskId)
207
+
208
+ // Outer capture has level-1 events with rootSessionId === session.id,
209
+ // depth 1. The nested capture has level-2 events with rootSessionId
210
+ // also === session.id (the whole tree shares a root) and depth 2.
211
+ const outerLineages = outerCaptured
212
+ .filter((e) => 'lineage' in e && e.lineage)
213
+ .map((e) => {
214
+ const l = (e as unknown as { lineage: { rootSessionId: string; depth: number } }).lineage
215
+ return { rootSessionId: l.rootSessionId, depth: l.depth }
216
+ })
217
+ expect(outerLineages.length).toBeGreaterThan(0)
218
+ for (const l of outerLineages) {
219
+ expect(l.rootSessionId).toBe(session.id)
220
+ expect(l.depth).toBe(1)
221
+ }
222
+
223
+ // Nested level-2 events: same rootSessionId, depth 2.
224
+ const nestedLineages = nestedEventsCaptured
225
+ .filter((e) => 'lineage' in e && e.lineage)
226
+ .map((e) => {
227
+ const l = (e as unknown as { lineage: { rootSessionId: string; depth: number } }).lineage
228
+ return { rootSessionId: l.rootSessionId, depth: l.depth }
229
+ })
230
+ expect(nestedLineages.length).toBeGreaterThan(0)
231
+ for (const l of nestedLineages) {
232
+ expect(l.rootSessionId).toBe(session.id)
233
+ expect(l.depth).toBe(2)
234
+ }
235
+ })
236
+
237
+ it('self vs tree depth filter: outer listener sees only its session events; nested listener sees its own tree', async () => {
238
+ // The subscribe-time depth filter is implemented at the listener
239
+ // injection seam — the parent passes a listener that captures events
240
+ // from its own sendMessage call. A nested child's sendMessage receives
241
+ // its own listener — the outer listener does NOT see the nested
242
+ // listener's events (no cross-contamination).
243
+ const harness = buildHarness()
244
+ const { project, thread, session, actor } = await seedActiveParent(harness)
245
+
246
+ const outerCaptured: RunEvent[] = []
247
+ const nestedCaptured: RunEvent[] = []
248
+
249
+ const leafAgent = buildAgent('leaf', 'leaf')
250
+ const midAgent = buildAgentCustom(
251
+ 'mid',
252
+ async (_input: AgentInput, config: BaseAgentConfig): Promise<BaseAgentResult> => {
253
+ if (!config.sessionId || !config.threadId || !config.projectId || !config.tenantId) {
254
+ throw new Error('mid missing scope')
255
+ }
256
+ const cs = await harness.store.getSession(config.sessionId, config.tenantId)
257
+ if (cs && cs.status !== 'active') {
258
+ await harness.store.updateSession({ ...cs, status: 'active' }, config.tenantId)
259
+ }
260
+ const inner = await harness.manager.sendMessage(
261
+ {
262
+ agentId: 'leaf',
263
+ input: { messages: [], workingDirectory: '/tmp' },
264
+ parentSessionId: config.sessionId,
265
+ tenantId: config.tenantId,
266
+ projectId: config.projectId,
267
+ parentActor: {
268
+ kind: 'agent',
269
+ agentId: 'mid' as never,
270
+ tenantId: config.tenantId,
271
+ },
272
+ },
273
+ {
274
+ parentRunId: 'run_mid_inner' as RunId,
275
+ parentAgentId: 'mid',
276
+ parentAbortController: new AbortController(),
277
+ depth: 1,
278
+ budgetTracker: { total: 10_000, remaining: 10_000 },
279
+ tenantId: config.tenantId,
280
+ threadId: config.threadId,
281
+ sessionId: config.sessionId,
282
+ projectId: config.projectId,
283
+ parentActor: {
284
+ kind: 'agent',
285
+ agentId: 'mid' as never,
286
+ tenantId: config.tenantId,
287
+ },
288
+ },
289
+ (ev) => {
290
+ nestedCaptured.push(ev)
291
+ },
292
+ )
293
+ await harness.manager.waitForCompletion(inner.taskId)
294
+ return {
295
+ runId: 'run_mid_done' as RunId,
296
+ status: 'completed',
297
+ usage: { ...EMPTY_TOKEN_USAGE },
298
+ cost: { ...ZERO_COST },
299
+ iterations: 1,
300
+ durationMs: 1,
301
+ messages: [createAssistantMessage('mid')],
302
+ result: 'mid',
303
+ }
304
+ },
305
+ )
306
+
307
+ harness.registry.register(buildDefinition(leafAgent))
308
+ harness.registry.register(buildDefinition(midAgent))
309
+
310
+ const task = await harness.manager.sendMessage(
311
+ buildSendMessageOptions({
312
+ agentId: 'mid',
313
+ parentSessionId: session.id,
314
+ projectId: project.id,
315
+ tenantId: DEFAULT_TENANT,
316
+ parentActor: actor,
317
+ }),
318
+ buildTaskContext({
319
+ sessionId: session.id,
320
+ projectId: project.id,
321
+ threadId: thread.id,
322
+ tenantId: DEFAULT_TENANT,
323
+ parentActor: actor,
324
+ }),
325
+ (ev) => {
326
+ outerCaptured.push(ev)
327
+ },
328
+ )
329
+ await harness.manager.waitForCompletion(task.taskId)
330
+
331
+ // Outer only sees its own spawn events (depth 1).
332
+ const outerSpawnedDepths = outerCaptured
333
+ .filter((e) => e.type === 'subsession_spawned')
334
+ .map((e) => ('lineage' in e && e.lineage ? e.lineage.depth : -1))
335
+ expect(outerSpawnedDepths).toEqual([1])
336
+
337
+ // Nested listener only sees its own spawn events (depth 2).
338
+ const nestedSpawnedDepths = nestedCaptured
339
+ .filter((e) => e.type === 'subsession_spawned')
340
+ .map((e) => ('lineage' in e && e.lineage ? e.lineage.depth : -1))
341
+ expect(nestedSpawnedDepths).toEqual([2])
342
+
343
+ // Cross-contamination sentinel: outer listener MUST NOT contain any
344
+ // depth-2 events (those belong to the nested scope).
345
+ const outerDepths = outerCaptured
346
+ .filter((e) => 'lineage' in e && e.lineage)
347
+ .map((e) => ('lineage' in e && e.lineage ? e.lineage.depth : -1))
348
+ expect(outerDepths.every((d) => d === 1)).toBe(true)
349
+ })
350
+
351
+ it('run_started and other core RunEvents also carry schemaVersion: 2 when stamped by the child listener wrapper', async () => {
352
+ // The listener wrapper in `manager/agent/lifecycle.ts#wrapChildListener`
353
+ // stamps `schemaVersion: 2` + `lineage` on EVERY event emitted inside
354
+ // the child's run. Core events that pass through the wrapped listener
355
+ // therefore inherit the envelope even though they have no lineage in
356
+ // their own type definition.
357
+ const harness = buildHarness()
358
+ const { project, thread, session, actor } = await seedActiveParent(harness)
359
+
360
+ const leafAgent = buildAgentCustom(
361
+ 'leaf-emit',
362
+ async (_i, _c, listener): Promise<BaseAgentResult> => {
363
+ // Emit a core event inside the child's run via the listener passed in.
364
+ await listener?.({
365
+ type: 'run_started',
366
+ runId: 'run_child_inner' as RunId,
367
+ })
368
+ return {
369
+ runId: 'run_child_inner' as RunId,
370
+ status: 'completed',
371
+ usage: { ...EMPTY_TOKEN_USAGE },
372
+ cost: { ...ZERO_COST },
373
+ iterations: 1,
374
+ durationMs: 1,
375
+ messages: [createAssistantMessage('done')],
376
+ result: 'done',
377
+ }
378
+ },
379
+ )
380
+ harness.registry.register(buildDefinition(leafAgent))
381
+
382
+ const captured: RunEvent[] = []
383
+ const task = await harness.manager.sendMessage(
384
+ buildSendMessageOptions({
385
+ agentId: 'leaf-emit',
386
+ parentSessionId: session.id,
387
+ projectId: project.id,
388
+ tenantId: DEFAULT_TENANT,
389
+ parentActor: actor,
390
+ }),
391
+ buildTaskContext({
392
+ sessionId: session.id,
393
+ projectId: project.id,
394
+ threadId: thread.id,
395
+ tenantId: DEFAULT_TENANT,
396
+ parentActor: actor,
397
+ }),
398
+ (ev) => {
399
+ captured.push(ev)
400
+ },
401
+ )
402
+ await harness.manager.waitForCompletion(task.taskId)
403
+
404
+ const runStarted = captured.find((e) => e.type === 'run_started')
405
+ expect(runStarted).toBeDefined()
406
+ if (runStarted && 'schemaVersion' in runStarted) {
407
+ expect(runStarted.schemaVersion).toBe(2)
408
+ }
409
+ })
410
+ })
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Integration — broadcast handoff atomic fan-out + rollback wired through
3
+ * the real stack.
4
+ *
5
+ * Covers roadmap §5 invariants: §5.4 (source → `awaiting_merge` after
6
+ * successful commit), §6.2 (broadcast atomic rollback — zero orphan
7
+ * sub-sessions/sessions after rollback via `deleteSubSession` +
8
+ * `deleteSession`), §10.2 (broadcast.rollback event carries accurate
9
+ * partialState counts).
10
+ */
11
+
12
+ import { describe, expect, it, vi } from 'vitest'
13
+ import { ThreadManager } from '../../../manager/thread/lifecycle.js'
14
+ import { InMemorySessionStore } from '../../../store/session/memory.js'
15
+ import { InMemoryThreadStore } from '../../../store/thread/memory.js'
16
+ import type { SessionId } from '../../../types/ids/index.js'
17
+ import type { ProjectId, ThreadId } from '../../../types/session/ids.js'
18
+ import { generateHandoffId } from '../../../utils/id.js'
19
+ import type { HandoffAssignment } from '../../handoff/assignment.js'
20
+ import { type BroadcastHandoffDeps, executeBroadcastHandoff } from '../../handoff/broadcast.js'
21
+ import { DefaultCapacityValidator } from '../../handoff/capacity.js'
22
+ import type { HandoffEventSink } from '../../handoff/events.js'
23
+ import type { ActorRef } from '../../hierarchy/actor.js'
24
+ import type { ExecFile } from '../../workspace/git-worktree.js'
25
+ import { GitWorktreeDriver } from '../../workspace/git-worktree.js'
26
+ import { WorkspaceBackendRegistry } from '../../workspace/registry.js'
27
+ import { DEFAULT_TENANT, okExec, stubLogger, userActor } from './_fixtures.js'
28
+
29
+ function buildDeps(
30
+ store: InMemorySessionStore,
31
+ threadStore: InMemoryThreadStore,
32
+ execOverride?: ExecFile,
33
+ ): {
34
+ deps: BroadcastHandoffDeps
35
+ events: HandoffEventSink & { onBroadcastRollback: ReturnType<typeof vi.fn> }
36
+ } {
37
+ const exec: ExecFile = execOverride ?? (async () => okExec())
38
+ const driver = new GitWorktreeDriver({
39
+ repoRoot: '/repo',
40
+ logger: stubLogger(),
41
+ execFile: exec,
42
+ })
43
+ const workspaceRegistry = new WorkspaceBackendRegistry()
44
+ workspaceRegistry.register(driver)
45
+
46
+ const onBroadcastRollback = vi.fn()
47
+ const sink: HandoffEventSink = {
48
+ onLocked: vi.fn(),
49
+ onUnlocked: vi.fn(),
50
+ onCommitted: vi.fn(),
51
+ onBroadcastRollback,
52
+ }
53
+
54
+ return {
55
+ deps: {
56
+ store,
57
+ workspaceRegistry,
58
+ capacity: new DefaultCapacityValidator(store),
59
+ events: sink,
60
+ threadManager: new ThreadManager({ threadStore, sessionStore: store }),
61
+ },
62
+ events: { ...sink, onBroadcastRollback },
63
+ }
64
+ }
65
+
66
+ function buildAssignments(
67
+ sourceSessionId: SessionId,
68
+ projectId: ProjectId,
69
+ threadId: ThreadId,
70
+ recipients: ActorRef[],
71
+ broadcastId = 'bc_integration',
72
+ expectedOwnerVersion = 0,
73
+ ): HandoffAssignment[] {
74
+ return recipients.map((recipientActor) => ({
75
+ id: generateHandoffId(),
76
+ mode: 'broadcast' as const,
77
+ sourceSessionId,
78
+ tenantId: DEFAULT_TENANT,
79
+ threadId,
80
+ projectId,
81
+ sourceActor: userActor('usr_source'),
82
+ recipientActor,
83
+ expectedOwnerVersion,
84
+ broadcastId,
85
+ createdAt: new Date('2026-04-17'),
86
+ }))
87
+ }
88
+
89
+ describe('Integration — broadcast handoff E2E', () => {
90
+ it('happy: 3-recipient fan-out → each recipient has isolated worktree + source reaches awaiting_merge', async () => {
91
+ const store = new InMemorySessionStore()
92
+ const threadStore = new InMemoryThreadStore()
93
+ const project = await store.createProject(
94
+ { tenantId: DEFAULT_TENANT, name: 'bc-happy' },
95
+ DEFAULT_TENANT,
96
+ )
97
+ const thread = await threadStore.createThread(
98
+ { projectId: project.id, title: 'bc-happy' },
99
+ DEFAULT_TENANT,
100
+ )
101
+ const source = await store.createSession(
102
+ { threadId: thread.id, projectId: project.id, currentActor: userActor('usr_source') },
103
+ DEFAULT_TENANT,
104
+ )
105
+
106
+ // Track each `worktree add` call so we can assert each recipient got a
107
+ // distinct worktree path (isolation).
108
+ const addCalls: string[] = []
109
+ const exec: ExecFile = async (_file, args) => {
110
+ if (args.includes('add')) {
111
+ // args contains ['-C', ..., 'worktree', 'add', '-b', branch, path].
112
+ const path = args[args.length - 1]
113
+ if (typeof path === 'string') addCalls.push(path)
114
+ }
115
+ return okExec()
116
+ }
117
+ const { deps } = buildDeps(store, threadStore, exec)
118
+
119
+ const recipients = [userActor('usr_bob'), userActor('usr_carol'), userActor('usr_dan')]
120
+ const assignments = buildAssignments(source.id, project.id, thread.id, recipients)
121
+
122
+ const outcomes = await executeBroadcastHandoff(deps, assignments, DEFAULT_TENANT)
123
+ expect(outcomes).toHaveLength(3)
124
+ expect(new Set(outcomes.map((o) => o.newSessionId)).size).toBe(3)
125
+ expect(new Set(outcomes.map((o) => o.workspaceId)).size).toBe(3)
126
+
127
+ // Each recipient landed on a distinct worktree path — isolation holds.
128
+ expect(new Set(addCalls).size).toBe(3)
129
+
130
+ // §5.4: source transitions to awaiting_merge post-commit.
131
+ const reloaded = await store.getSession(source.id, DEFAULT_TENANT)
132
+ expect(reloaded?.status).toBe('awaiting_merge')
133
+
134
+ // Three children visible via getChildren.
135
+ const children = await store.getChildren(source.id, DEFAULT_TENANT)
136
+ expect(children).toHaveLength(3)
137
+ expect(children.every((c) => c.kind === 'user_handoff')).toBe(true)
138
+ })
139
+
140
+ it('rollback on 2nd-recipient provisioning failure: zero orphan records, partialState accurate', async () => {
141
+ const store = new InMemorySessionStore()
142
+ const threadStore = new InMemoryThreadStore()
143
+ const project = await store.createProject(
144
+ { tenantId: DEFAULT_TENANT, name: 'bc-rb' },
145
+ DEFAULT_TENANT,
146
+ )
147
+ const thread = await threadStore.createThread(
148
+ { projectId: project.id, title: 'bc-rb' },
149
+ DEFAULT_TENANT,
150
+ )
151
+ const source = await store.createSession(
152
+ { threadId: thread.id, projectId: project.id, currentActor: userActor('usr_source') },
153
+ DEFAULT_TENANT,
154
+ )
155
+
156
+ let addCount = 0
157
+ const exec: ExecFile = async (_file, args) => {
158
+ if (args.includes('add')) {
159
+ addCount += 1
160
+ if (addCount === 2) throw new Error('simulated fault on 2nd recipient')
161
+ }
162
+ return okExec()
163
+ }
164
+ const { deps, events } = buildDeps(store, threadStore, exec)
165
+
166
+ const assignments = buildAssignments(source.id, project.id, thread.id, [
167
+ userActor('usr_b'),
168
+ userActor('usr_c'),
169
+ userActor('usr_d'),
170
+ ])
171
+
172
+ await expect(executeBroadcastHandoff(deps, assignments, DEFAULT_TENANT)).rejects.toThrow(
173
+ /Workspace backend git-worktree failed on create/,
174
+ )
175
+
176
+ // Phase 8 closed the Known Delta: rollback now calls deleteSubSession +
177
+ // deleteSession rather than flipping to 'archived'. Zero orphan
178
+ // sub-session records remain.
179
+ const children = await store.getChildren(source.id, DEFAULT_TENANT)
180
+ expect(children).toHaveLength(0)
181
+
182
+ // Source reverted to idle with original ownerVersion.
183
+ const reloaded = await store.getSession(source.id, DEFAULT_TENANT)
184
+ expect(reloaded?.status).toBe('idle')
185
+ expect(reloaded?.ownerVersion).toBe(0)
186
+
187
+ // onBroadcastRollback emitted with accurate counts.
188
+ expect(events.onBroadcastRollback).toHaveBeenCalledTimes(1)
189
+ const rollbackCall = events.onBroadcastRollback.mock.calls[0]?.[0] as
190
+ | {
191
+ partialState: {
192
+ worktreesProvisioned: number
193
+ subsessionsCreated: number
194
+ assignmentsWritten: number
195
+ }
196
+ }
197
+ | undefined
198
+ expect(rollbackCall?.partialState.worktreesProvisioned).toBe(1)
199
+ expect(rollbackCall?.partialState.subsessionsCreated).toBe(1)
200
+ expect(rollbackCall?.partialState.assignmentsWritten).toBe(1)
201
+ })
202
+
203
+ it('source transitions to awaiting_merge + retains currentActor as coordinator (§5.4)', async () => {
204
+ const store = new InMemorySessionStore()
205
+ const threadStore = new InMemoryThreadStore()
206
+ const project = await store.createProject(
207
+ { tenantId: DEFAULT_TENANT, name: 'coord' },
208
+ DEFAULT_TENANT,
209
+ )
210
+ const thread = await threadStore.createThread(
211
+ { projectId: project.id, title: 'coord' },
212
+ DEFAULT_TENANT,
213
+ )
214
+ const coordinator = userActor('usr_source')
215
+ const source = await store.createSession(
216
+ { threadId: thread.id, projectId: project.id, currentActor: coordinator },
217
+ DEFAULT_TENANT,
218
+ )
219
+
220
+ const { deps } = buildDeps(store, threadStore)
221
+ const assignments = buildAssignments(source.id, project.id, thread.id, [
222
+ userActor('usr_b'),
223
+ userActor('usr_c'),
224
+ ])
225
+
226
+ await executeBroadcastHandoff(deps, assignments, DEFAULT_TENANT)
227
+
228
+ const reloaded = await store.getSession(source.id, DEFAULT_TENANT)
229
+ expect(reloaded?.status).toBe('awaiting_merge')
230
+ // Coordinator retained as current actor (§5.4).
231
+ expect(reloaded?.currentActor).toEqual(coordinator)
232
+ expect(reloaded?.ownerVersion).toBe(1)
233
+ })
234
+
235
+ it('all recipients get isolated worktrees — zero path collisions even under N=8', async () => {
236
+ const store = new InMemorySessionStore()
237
+ const threadStore = new InMemoryThreadStore()
238
+ const project = await store.createProject(
239
+ { tenantId: DEFAULT_TENANT, name: 'iso' },
240
+ DEFAULT_TENANT,
241
+ )
242
+ const thread = await threadStore.createThread(
243
+ { projectId: project.id, title: 'iso' },
244
+ DEFAULT_TENANT,
245
+ )
246
+ const source = await store.createSession(
247
+ { threadId: thread.id, projectId: project.id, currentActor: userActor('usr_source') },
248
+ DEFAULT_TENANT,
249
+ )
250
+
251
+ const seenPaths = new Set<string>()
252
+ const exec: ExecFile = async (_file, args) => {
253
+ if (args.includes('add')) {
254
+ const path = args[args.length - 1]
255
+ if (typeof path === 'string') {
256
+ if (seenPaths.has(path)) throw new Error(`path collision: ${path}`)
257
+ seenPaths.add(path)
258
+ }
259
+ }
260
+ return okExec()
261
+ }
262
+ const { deps } = buildDeps(store, threadStore, exec)
263
+
264
+ const recipients = Array.from({ length: 8 }, (_, i) => userActor(`usr_${i}`))
265
+ const assignments = buildAssignments(source.id, project.id, thread.id, recipients)
266
+
267
+ const outcomes = await executeBroadcastHandoff(deps, assignments, DEFAULT_TENANT)
268
+ expect(outcomes).toHaveLength(8)
269
+ expect(seenPaths.size).toBe(8)
270
+ })
271
+ })