@namzu/sdk 0.1.7 → 0.2.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 (532) hide show
  1. package/CHANGELOG.md +23 -5
  2. package/README.md +14 -9
  3. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  4. package/dist/agents/ReactiveAgent.js +5 -3
  5. package/dist/agents/ReactiveAgent.js.map +1 -1
  6. package/dist/agents/RouterAgent.d.ts.map +1 -1
  7. package/dist/agents/RouterAgent.js +3 -0
  8. package/dist/agents/RouterAgent.js.map +1 -1
  9. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  10. package/dist/agents/SupervisorAgent.js +18 -5
  11. package/dist/agents/SupervisorAgent.js.map +1 -1
  12. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  13. package/dist/bridge/a2a/mapper.js +6 -0
  14. package/dist/bridge/a2a/mapper.js.map +1 -1
  15. package/dist/bridge/a2a/task.d.ts +2 -2
  16. package/dist/bridge/a2a/task.d.ts.map +1 -1
  17. package/dist/bridge/a2a/task.js.map +1 -1
  18. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  19. package/dist/bridge/sse/mapper.js +6 -0
  20. package/dist/bridge/sse/mapper.js.map +1 -1
  21. package/dist/constants/a2a/index.d.ts +2 -2
  22. package/dist/constants/a2a/index.d.ts.map +1 -1
  23. package/dist/constants/a2a/index.js.map +1 -1
  24. package/dist/contracts/api.d.ts +22 -3
  25. package/dist/contracts/api.d.ts.map +1 -1
  26. package/dist/contracts/index.d.ts +3 -1
  27. package/dist/contracts/index.d.ts.map +1 -1
  28. package/dist/contracts/index.js.map +1 -1
  29. package/dist/gateway/local.d.ts.map +1 -1
  30. package/dist/gateway/local.js +6 -0
  31. package/dist/gateway/local.js.map +1 -1
  32. package/dist/index.d.ts +4 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
  37. package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
  38. package/dist/manager/agent/__tests__/lifecycle.test.js +302 -0
  39. package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
  40. package/dist/manager/agent/lifecycle.d.ts +58 -3
  41. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  42. package/dist/manager/agent/lifecycle.js +311 -12
  43. package/dist/manager/agent/lifecycle.js.map +1 -1
  44. package/dist/manager/run/persistence.d.ts +8 -1
  45. package/dist/manager/run/persistence.d.ts.map +1 -1
  46. package/dist/manager/run/persistence.js +15 -0
  47. package/dist/manager/run/persistence.js.map +1 -1
  48. package/dist/run/reporter.d.ts.map +1 -1
  49. package/dist/run/reporter.js +25 -0
  50. package/dist/run/reporter.js.map +1 -1
  51. package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
  52. package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
  53. package/dist/runtime/query/__tests__/context.test.js +84 -0
  54. package/dist/runtime/query/__tests__/context.test.js.map +1 -0
  55. package/dist/runtime/query/context.d.ts +55 -2
  56. package/dist/runtime/query/context.d.ts.map +1 -1
  57. package/dist/runtime/query/context.js +48 -8
  58. package/dist/runtime/query/context.js.map +1 -1
  59. package/dist/runtime/query/events.d.ts.map +1 -1
  60. package/dist/runtime/query/events.js +8 -0
  61. package/dist/runtime/query/events.js.map +1 -1
  62. package/dist/runtime/query/index.d.ts +25 -2
  63. package/dist/runtime/query/index.d.ts.map +1 -1
  64. package/dist/runtime/query/index.js +11 -1
  65. package/dist/runtime/query/index.js.map +1 -1
  66. package/dist/session/__tests__/integration/_fixtures.d.ts +115 -0
  67. package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
  68. package/dist/session/__tests__/integration/_fixtures.js +198 -0
  69. package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
  70. package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
  71. package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
  72. package/dist/session/__tests__/integration/capacity-caps.test.js +116 -0
  73. package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
  74. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
  75. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
  76. package/dist/session/__tests__/integration/e2e-spawn.test.js +226 -0
  77. package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
  78. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
  79. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
  80. package/dist/session/__tests__/integration/event-stream-ordering.test.js +323 -0
  81. package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
  82. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
  83. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
  84. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +170 -0
  85. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
  86. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
  87. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
  88. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +146 -0
  89. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
  90. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
  91. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
  92. package/dist/session/__tests__/integration/handoff-single-e2e.test.js +163 -0
  93. package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
  94. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
  95. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
  96. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +157 -0
  97. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
  98. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
  99. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
  100. package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
  101. package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
  102. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
  103. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
  104. package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
  105. package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
  106. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
  107. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
  108. package/dist/session/__tests__/integration/prev-artifact-dag.test.js +241 -0
  109. package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
  110. package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
  111. package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
  112. package/dist/session/__tests__/integration/retention-archive.test.js +186 -0
  113. package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
  114. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
  115. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
  116. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +200 -0
  117. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
  118. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
  119. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
  120. package/dist/session/__tests__/integration/tenant-isolation.test.js +180 -0
  121. package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
  122. package/dist/session/errors.d.ts +60 -0
  123. package/dist/session/errors.d.ts.map +1 -0
  124. package/dist/session/errors.js +50 -0
  125. package/dist/session/errors.js.map +1 -0
  126. package/dist/session/events/index.d.ts +4 -0
  127. package/dist/session/events/index.d.ts.map +1 -0
  128. package/dist/session/events/index.js +8 -0
  129. package/dist/session/events/index.js.map +1 -0
  130. package/dist/session/events/schema-version.d.ts +13 -0
  131. package/dist/session/events/schema-version.d.ts.map +1 -0
  132. package/dist/session/events/schema-version.js +12 -0
  133. package/dist/session/events/schema-version.js.map +1 -0
  134. package/dist/session/events/types.d.ts +64 -0
  135. package/dist/session/events/types.d.ts.map +1 -0
  136. package/dist/session/events/types.js +2 -0
  137. package/dist/session/events/types.js.map +1 -0
  138. package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
  139. package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
  140. package/dist/session/handoff/__tests__/broadcast.test.js +243 -0
  141. package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
  142. package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
  143. package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
  144. package/dist/session/handoff/__tests__/capacity.test.js +100 -0
  145. package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
  146. package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
  147. package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
  148. package/dist/session/handoff/__tests__/single.test.js +230 -0
  149. package/dist/session/handoff/__tests__/single.test.js.map +1 -0
  150. package/dist/session/handoff/assignment.d.ts +59 -0
  151. package/dist/session/handoff/assignment.d.ts.map +1 -0
  152. package/dist/session/handoff/assignment.js +11 -0
  153. package/dist/session/handoff/assignment.js.map +1 -0
  154. package/dist/session/handoff/broadcast.d.ts +47 -0
  155. package/dist/session/handoff/broadcast.d.ts.map +1 -0
  156. package/dist/session/handoff/broadcast.js +296 -0
  157. package/dist/session/handoff/broadcast.js.map +1 -0
  158. package/dist/session/handoff/capacity.d.ts +66 -0
  159. package/dist/session/handoff/capacity.d.ts.map +1 -0
  160. package/dist/session/handoff/capacity.js +60 -0
  161. package/dist/session/handoff/capacity.js.map +1 -0
  162. package/dist/session/handoff/events.d.ts +66 -0
  163. package/dist/session/handoff/events.d.ts.map +1 -0
  164. package/dist/session/handoff/events.js +13 -0
  165. package/dist/session/handoff/events.js.map +1 -0
  166. package/dist/session/handoff/index.d.ts +12 -0
  167. package/dist/session/handoff/index.d.ts.map +1 -0
  168. package/dist/session/handoff/index.js +9 -0
  169. package/dist/session/handoff/index.js.map +1 -0
  170. package/dist/session/handoff/single.d.ts +62 -0
  171. package/dist/session/handoff/single.d.ts.map +1 -0
  172. package/dist/session/handoff/single.js +217 -0
  173. package/dist/session/handoff/single.js.map +1 -0
  174. package/dist/session/handoff/version.d.ts +52 -0
  175. package/dist/session/handoff/version.d.ts.map +1 -0
  176. package/dist/session/handoff/version.js +36 -0
  177. package/dist/session/handoff/version.js.map +1 -0
  178. package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
  179. package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
  180. package/dist/session/hierarchy/__tests__/session.test.js +67 -0
  181. package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
  182. package/dist/session/hierarchy/actor.d.ts +26 -0
  183. package/dist/session/hierarchy/actor.d.ts.map +1 -0
  184. package/dist/session/hierarchy/actor.js +2 -0
  185. package/dist/session/hierarchy/actor.js.map +1 -0
  186. package/dist/session/hierarchy/index.d.ts +8 -0
  187. package/dist/session/hierarchy/index.d.ts.map +1 -0
  188. package/dist/session/hierarchy/index.js +4 -0
  189. package/dist/session/hierarchy/index.js.map +1 -0
  190. package/dist/session/hierarchy/lineage.d.ts +15 -0
  191. package/dist/session/hierarchy/lineage.d.ts.map +1 -0
  192. package/dist/session/hierarchy/lineage.js +2 -0
  193. package/dist/session/hierarchy/lineage.js.map +1 -0
  194. package/dist/session/hierarchy/project.d.ts +40 -0
  195. package/dist/session/hierarchy/project.d.ts.map +1 -0
  196. package/dist/session/hierarchy/project.js +2 -0
  197. package/dist/session/hierarchy/project.js.map +1 -0
  198. package/dist/session/hierarchy/session.d.ts +59 -0
  199. package/dist/session/hierarchy/session.d.ts.map +1 -0
  200. package/dist/session/hierarchy/session.js +51 -0
  201. package/dist/session/hierarchy/session.js.map +1 -0
  202. package/dist/session/hierarchy/sub-session.d.ts +76 -0
  203. package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
  204. package/dist/session/hierarchy/sub-session.js +2 -0
  205. package/dist/session/hierarchy/sub-session.js.map +1 -0
  206. package/dist/session/hierarchy/tenant.d.ts +13 -0
  207. package/dist/session/hierarchy/tenant.d.ts.map +1 -0
  208. package/dist/session/hierarchy/tenant.js +2 -0
  209. package/dist/session/hierarchy/tenant.js.map +1 -0
  210. package/dist/session/index.d.ts +10 -0
  211. package/dist/session/index.d.ts.map +1 -0
  212. package/dist/session/index.js +15 -0
  213. package/dist/session/index.js.map +1 -0
  214. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
  215. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
  216. package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
  217. package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
  218. package/dist/session/intervention/index.d.ts +3 -0
  219. package/dist/session/intervention/index.d.ts.map +1 -0
  220. package/dist/session/intervention/index.js +8 -0
  221. package/dist/session/intervention/index.js.map +1 -0
  222. package/dist/session/intervention/prev-artifact.d.ts +103 -0
  223. package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
  224. package/dist/session/intervention/prev-artifact.js +112 -0
  225. package/dist/session/intervention/prev-artifact.js.map +1 -0
  226. package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
  227. package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
  228. package/dist/session/migration/__tests__/filesystem.test.js +188 -0
  229. package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
  230. package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
  231. package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
  232. package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
  233. package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
  234. package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
  235. package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
  236. package/dist/session/migration/__tests__/marker.test.js +75 -0
  237. package/dist/session/migration/__tests__/marker.test.js.map +1 -0
  238. package/dist/session/migration/errors.d.ts +26 -0
  239. package/dist/session/migration/errors.d.ts.map +1 -0
  240. package/dist/session/migration/errors.js +22 -0
  241. package/dist/session/migration/errors.js.map +1 -0
  242. package/dist/session/migration/filesystem.d.ts +94 -0
  243. package/dist/session/migration/filesystem.d.ts.map +1 -0
  244. package/dist/session/migration/filesystem.js +319 -0
  245. package/dist/session/migration/filesystem.js.map +1 -0
  246. package/dist/session/migration/id-prefix.d.ts +98 -0
  247. package/dist/session/migration/id-prefix.d.ts.map +1 -0
  248. package/dist/session/migration/id-prefix.js +116 -0
  249. package/dist/session/migration/id-prefix.js.map +1 -0
  250. package/dist/session/migration/index.d.ts +8 -0
  251. package/dist/session/migration/index.d.ts.map +1 -0
  252. package/dist/session/migration/index.js +8 -0
  253. package/dist/session/migration/index.js.map +1 -0
  254. package/dist/session/migration/marker.d.ts +57 -0
  255. package/dist/session/migration/marker.d.ts.map +1 -0
  256. package/dist/session/migration/marker.js +111 -0
  257. package/dist/session/migration/marker.js.map +1 -0
  258. package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
  259. package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
  260. package/dist/session/retention/__tests__/archive.test.js +252 -0
  261. package/dist/session/retention/__tests__/archive.test.js.map +1 -0
  262. package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
  263. package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
  264. package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
  265. package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
  266. package/dist/session/retention/archive-backend-ref.d.ts +18 -0
  267. package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
  268. package/dist/session/retention/archive-backend-ref.js +2 -0
  269. package/dist/session/retention/archive-backend-ref.js.map +1 -0
  270. package/dist/session/retention/archive.d.ts +130 -0
  271. package/dist/session/retention/archive.d.ts.map +1 -0
  272. package/dist/session/retention/archive.js +203 -0
  273. package/dist/session/retention/archive.js.map +1 -0
  274. package/dist/session/retention/backend.d.ts +101 -0
  275. package/dist/session/retention/backend.d.ts.map +1 -0
  276. package/dist/session/retention/backend.js +15 -0
  277. package/dist/session/retention/backend.js.map +1 -0
  278. package/dist/session/retention/disk-backend.d.ts +59 -0
  279. package/dist/session/retention/disk-backend.d.ts.map +1 -0
  280. package/dist/session/retention/disk-backend.js +236 -0
  281. package/dist/session/retention/disk-backend.js.map +1 -0
  282. package/dist/session/retention/index.d.ts +9 -0
  283. package/dist/session/retention/index.d.ts.map +1 -0
  284. package/dist/session/retention/index.js +6 -0
  285. package/dist/session/retention/index.js.map +1 -0
  286. package/dist/session/retention/policy.d.ts +49 -0
  287. package/dist/session/retention/policy.d.ts.map +1 -0
  288. package/dist/session/retention/policy.js +21 -0
  289. package/dist/session/retention/policy.js.map +1 -0
  290. package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
  291. package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
  292. package/dist/session/summary/__tests__/materialize.test.js +269 -0
  293. package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
  294. package/dist/session/summary/deliverable.d.ts +74 -0
  295. package/dist/session/summary/deliverable.d.ts.map +1 -0
  296. package/dist/session/summary/deliverable.js +20 -0
  297. package/dist/session/summary/deliverable.js.map +1 -0
  298. package/dist/session/summary/index.d.ts +6 -0
  299. package/dist/session/summary/index.d.ts.map +1 -0
  300. package/dist/session/summary/index.js +9 -0
  301. package/dist/session/summary/index.js.map +1 -0
  302. package/dist/session/summary/materialize.d.ts +82 -0
  303. package/dist/session/summary/materialize.d.ts.map +1 -0
  304. package/dist/session/summary/materialize.js +117 -0
  305. package/dist/session/summary/materialize.js.map +1 -0
  306. package/dist/session/summary/ref.d.ts +91 -0
  307. package/dist/session/summary/ref.d.ts.map +1 -0
  308. package/dist/session/summary/ref.js +51 -0
  309. package/dist/session/summary/ref.js.map +1 -0
  310. package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
  311. package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
  312. package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
  313. package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
  314. package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
  315. package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
  316. package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
  317. package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
  318. package/dist/session/workspace/driver.d.ts +55 -0
  319. package/dist/session/workspace/driver.d.ts.map +1 -0
  320. package/dist/session/workspace/driver.js +12 -0
  321. package/dist/session/workspace/driver.js.map +1 -0
  322. package/dist/session/workspace/git-worktree.d.ts +65 -0
  323. package/dist/session/workspace/git-worktree.d.ts.map +1 -0
  324. package/dist/session/workspace/git-worktree.js +156 -0
  325. package/dist/session/workspace/git-worktree.js.map +1 -0
  326. package/dist/session/workspace/index.d.ts +8 -0
  327. package/dist/session/workspace/index.d.ts.map +1 -0
  328. package/dist/session/workspace/index.js +7 -0
  329. package/dist/session/workspace/index.js.map +1 -0
  330. package/dist/session/workspace/path-builder.d.ts +50 -0
  331. package/dist/session/workspace/path-builder.d.ts.map +1 -0
  332. package/dist/session/workspace/path-builder.js +50 -0
  333. package/dist/session/workspace/path-builder.js.map +1 -0
  334. package/dist/session/workspace/ref.d.ts +46 -0
  335. package/dist/session/workspace/ref.d.ts.map +1 -0
  336. package/dist/session/workspace/ref.js +11 -0
  337. package/dist/session/workspace/ref.js.map +1 -0
  338. package/dist/session/workspace/registry.d.ts +26 -0
  339. package/dist/session/workspace/registry.d.ts.map +1 -0
  340. package/dist/session/workspace/registry.js +35 -0
  341. package/dist/session/workspace/registry.js.map +1 -0
  342. package/dist/store/conversation/memory.d.ts +22 -0
  343. package/dist/store/conversation/memory.d.ts.map +1 -1
  344. package/dist/store/conversation/memory.js +22 -0
  345. package/dist/store/conversation/memory.js.map +1 -1
  346. package/dist/store/session/__tests__/disk.test.d.ts +2 -0
  347. package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
  348. package/dist/store/session/__tests__/disk.test.js +240 -0
  349. package/dist/store/session/__tests__/disk.test.js.map +1 -0
  350. package/dist/store/session/__tests__/memory.test.d.ts +2 -0
  351. package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
  352. package/dist/store/session/__tests__/memory.test.js +217 -0
  353. package/dist/store/session/__tests__/memory.test.js.map +1 -0
  354. package/dist/store/session/disk.d.ts +85 -0
  355. package/dist/store/session/disk.d.ts.map +1 -0
  356. package/dist/store/session/disk.js +757 -0
  357. package/dist/store/session/disk.js.map +1 -0
  358. package/dist/store/session/index.d.ts +7 -0
  359. package/dist/store/session/index.d.ts.map +1 -0
  360. package/dist/store/session/index.js +11 -0
  361. package/dist/store/session/index.js.map +1 -0
  362. package/dist/store/session/linkage.d.ts +38 -0
  363. package/dist/store/session/linkage.d.ts.map +1 -0
  364. package/dist/store/session/linkage.js +64 -0
  365. package/dist/store/session/linkage.js.map +1 -0
  366. package/dist/store/session/memory.d.ts +48 -0
  367. package/dist/store/session/memory.d.ts.map +1 -0
  368. package/dist/store/session/memory.js +322 -0
  369. package/dist/store/session/memory.js.map +1 -0
  370. package/dist/store/session/messages.d.ts +20 -0
  371. package/dist/store/session/messages.d.ts.map +1 -0
  372. package/dist/store/session/messages.js +12 -0
  373. package/dist/store/session/messages.js.map +1 -0
  374. package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
  375. package/dist/types/agent/base.d.ts +28 -1
  376. package/dist/types/agent/base.d.ts.map +1 -1
  377. package/dist/types/agent/task.d.ts +50 -2
  378. package/dist/types/agent/task.d.ts.map +1 -1
  379. package/dist/types/agent/task.js.map +1 -1
  380. package/dist/types/conversation/index.d.ts +7 -0
  381. package/dist/types/conversation/index.d.ts.map +1 -1
  382. package/dist/types/ids/index.d.ts +26 -3
  383. package/dist/types/ids/index.d.ts.map +1 -1
  384. package/dist/types/ids/index.js +8 -1
  385. package/dist/types/ids/index.js.map +1 -1
  386. package/dist/types/invocation/__tests__/state.test.js +36 -29
  387. package/dist/types/invocation/__tests__/state.test.js.map +1 -1
  388. package/dist/types/invocation/index.d.ts +20 -4
  389. package/dist/types/invocation/index.d.ts.map +1 -1
  390. package/dist/types/invocation/index.js +10 -7
  391. package/dist/types/invocation/index.js.map +1 -1
  392. package/dist/types/run/config.d.ts +11 -1
  393. package/dist/types/run/config.d.ts.map +1 -1
  394. package/dist/types/run/events.d.ts +26 -1
  395. package/dist/types/run/events.d.ts.map +1 -1
  396. package/dist/types/run/index.d.ts.map +1 -1
  397. package/dist/types/run/index.js +8 -0
  398. package/dist/types/run/index.js.map +1 -1
  399. package/dist/types/run/metadata.d.ts +24 -1
  400. package/dist/types/run/metadata.d.ts.map +1 -1
  401. package/dist/types/run/status.d.ts +26 -0
  402. package/dist/types/run/status.d.ts.map +1 -0
  403. package/dist/types/run/status.js +2 -0
  404. package/dist/types/run/status.js.map +1 -0
  405. package/dist/types/session/ids.d.ts +18 -0
  406. package/dist/types/session/ids.d.ts.map +1 -0
  407. package/dist/types/session/ids.js +12 -0
  408. package/dist/types/session/ids.js.map +1 -0
  409. package/dist/types/session/index.d.ts +3 -0
  410. package/dist/types/session/index.d.ts.map +1 -0
  411. package/dist/types/session/index.js +5 -0
  412. package/dist/types/session/index.js.map +1 -0
  413. package/dist/types/session/store.d.ts +188 -0
  414. package/dist/types/session/store.d.ts.map +1 -0
  415. package/dist/types/session/store.js +14 -0
  416. package/dist/types/session/store.js.map +1 -0
  417. package/dist/utils/id.d.ts +18 -1
  418. package/dist/utils/id.d.ts.map +1 -1
  419. package/dist/utils/id.js +42 -4
  420. package/dist/utils/id.js.map +1 -1
  421. package/package.json +1 -1
  422. package/src/agents/ReactiveAgent.ts +7 -3
  423. package/src/agents/RouterAgent.ts +5 -0
  424. package/src/agents/SupervisorAgent.ts +26 -6
  425. package/src/bridge/a2a/mapper.ts +7 -0
  426. package/src/bridge/a2a/task.ts +2 -2
  427. package/src/bridge/sse/mapper.ts +8 -1
  428. package/src/constants/a2a/index.ts +2 -2
  429. package/src/contracts/api.ts +23 -3
  430. package/src/contracts/index.ts +2 -0
  431. package/src/gateway/local.ts +6 -0
  432. package/src/index.ts +14 -0
  433. package/src/manager/agent/__tests__/lifecycle.test.ts +452 -0
  434. package/src/manager/agent/lifecycle.ts +434 -19
  435. package/src/manager/run/persistence.ts +20 -1
  436. package/src/run/reporter.ts +28 -0
  437. package/src/runtime/query/__tests__/context.test.ts +101 -0
  438. package/src/runtime/query/context.ts +106 -10
  439. package/src/runtime/query/events.ts +8 -0
  440. package/src/runtime/query/index.ts +41 -3
  441. package/src/session/__tests__/integration/_fixtures.ts +282 -0
  442. package/src/session/__tests__/integration/capacity-caps.test.ts +164 -0
  443. package/src/session/__tests__/integration/e2e-spawn.test.ts +278 -0
  444. package/src/session/__tests__/integration/event-stream-ordering.test.ts +403 -0
  445. package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +245 -0
  446. package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +179 -0
  447. package/src/session/__tests__/integration/handoff-single-e2e.test.ts +220 -0
  448. package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +237 -0
  449. package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
  450. package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
  451. package/src/session/__tests__/integration/prev-artifact-dag.test.ts +318 -0
  452. package/src/session/__tests__/integration/retention-archive.test.ts +231 -0
  453. package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +237 -0
  454. package/src/session/__tests__/integration/tenant-isolation.test.ts +282 -0
  455. package/src/session/errors.ts +70 -0
  456. package/src/session/events/index.ts +16 -0
  457. package/src/session/events/schema-version.ts +13 -0
  458. package/src/session/events/types.ts +71 -0
  459. package/src/session/handoff/__tests__/broadcast.test.ts +350 -0
  460. package/src/session/handoff/__tests__/capacity.test.ts +123 -0
  461. package/src/session/handoff/__tests__/single.test.ts +316 -0
  462. package/src/session/handoff/assignment.ts +62 -0
  463. package/src/session/handoff/broadcast.ts +381 -0
  464. package/src/session/handoff/capacity.ts +121 -0
  465. package/src/session/handoff/events.ts +72 -0
  466. package/src/session/handoff/index.ts +29 -0
  467. package/src/session/handoff/single.ts +288 -0
  468. package/src/session/handoff/version.ts +59 -0
  469. package/src/session/hierarchy/__tests__/session.test.ts +92 -0
  470. package/src/session/hierarchy/actor.ts +17 -0
  471. package/src/session/hierarchy/index.ts +17 -0
  472. package/src/session/hierarchy/lineage.ts +15 -0
  473. package/src/session/hierarchy/project.ts +41 -0
  474. package/src/session/hierarchy/session.ts +97 -0
  475. package/src/session/hierarchy/sub-session.ts +92 -0
  476. package/src/session/hierarchy/tenant.ts +13 -0
  477. package/src/session/index.ts +15 -0
  478. package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
  479. package/src/session/intervention/index.ts +16 -0
  480. package/src/session/intervention/prev-artifact.ts +180 -0
  481. package/src/session/migration/__tests__/filesystem.test.ts +263 -0
  482. package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
  483. package/src/session/migration/__tests__/marker.test.ts +84 -0
  484. package/src/session/migration/errors.ts +23 -0
  485. package/src/session/migration/filesystem.ts +401 -0
  486. package/src/session/migration/id-prefix.ts +146 -0
  487. package/src/session/migration/index.ts +38 -0
  488. package/src/session/migration/marker.ts +131 -0
  489. package/src/session/retention/__tests__/archive.test.ts +316 -0
  490. package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
  491. package/src/session/retention/archive-backend-ref.ts +17 -0
  492. package/src/session/retention/archive.ts +281 -0
  493. package/src/session/retention/backend.ts +107 -0
  494. package/src/session/retention/disk-backend.ts +304 -0
  495. package/src/session/retention/index.ts +16 -0
  496. package/src/session/retention/policy.ts +53 -0
  497. package/src/session/summary/__tests__/materialize.test.ts +341 -0
  498. package/src/session/summary/deliverable.ts +84 -0
  499. package/src/session/summary/index.ts +31 -0
  500. package/src/session/summary/materialize.ts +169 -0
  501. package/src/session/summary/ref.ts +104 -0
  502. package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
  503. package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
  504. package/src/session/workspace/driver.ts +60 -0
  505. package/src/session/workspace/git-worktree.ts +209 -0
  506. package/src/session/workspace/index.ts +25 -0
  507. package/src/session/workspace/path-builder.ts +71 -0
  508. package/src/session/workspace/ref.ts +50 -0
  509. package/src/session/workspace/registry.ts +42 -0
  510. package/src/store/conversation/memory.ts +23 -0
  511. package/src/store/session/__tests__/disk.test.ts +346 -0
  512. package/src/store/session/__tests__/memory.test.ts +327 -0
  513. package/src/store/session/disk.ts +920 -0
  514. package/src/store/session/index.ts +14 -0
  515. package/src/store/session/linkage.ts +80 -0
  516. package/src/store/session/memory.ts +400 -0
  517. package/src/store/session/messages.ts +21 -0
  518. package/src/types/agent/base.ts +31 -1
  519. package/src/types/agent/task.ts +58 -2
  520. package/src/types/conversation/index.ts +7 -0
  521. package/src/types/ids/index.ts +41 -3
  522. package/src/types/invocation/__tests__/state.test.ts +37 -29
  523. package/src/types/invocation/index.ts +26 -10
  524. package/src/types/run/config.ts +12 -1
  525. package/src/types/run/events.ts +36 -1
  526. package/src/types/run/index.ts +8 -0
  527. package/src/types/run/metadata.ts +24 -1
  528. package/src/types/run/status.ts +33 -0
  529. package/src/types/session/ids.ts +34 -0
  530. package/src/types/session/index.ts +28 -0
  531. package/src/types/session/store.ts +229 -0
  532. package/src/utils/id.ts +55 -4
@@ -1,6 +1,17 @@
1
1
  import { AGENT_MANAGER_DEFAULTS } from '../../constants/agent/index.js'
2
2
  import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js'
3
3
  import type { AgentRegistry } from '../../registry/agent/definitions.js'
4
+ import { RUN_EVENT_SCHEMA_VERSION } from '../../session/events/schema-version.js'
5
+ import {
6
+ type CapacityValidator,
7
+ DelegationCapacityExceeded,
8
+ } from '../../session/handoff/capacity.js'
9
+ import type { ActorRef } from '../../session/hierarchy/actor.js'
10
+ import type { Lineage } from '../../session/hierarchy/lineage.js'
11
+ import type { SessionSummaryMaterializer } from '../../session/summary/materialize.js'
12
+ import type { SessionSummaryOutcome } from '../../session/summary/ref.js'
13
+ import type { WorkspaceRef } from '../../session/workspace/ref.js'
14
+ import type { WorkspaceBackendRegistry } from '../../session/workspace/registry.js'
4
15
  import type { BaseAgentConfig, BaseAgentResult } from '../../types/agent/base.js'
5
16
  import type {
6
17
  AgentLifecycleEvent,
@@ -14,33 +25,79 @@ import type {
14
25
  SendMessageOptions,
15
26
  } from '../../types/agent/task.js'
16
27
  import { isTerminalAgentTaskState } from '../../types/agent/task.js'
17
- import type { RunId, TaskId } from '../../types/ids/index.js'
28
+ import type { AgentId, RunId, SessionId, TaskId, TenantId } from '../../types/ids/index.js'
18
29
  import type { Message } from '../../types/message/index.js'
30
+ import type { RunEvent, RunEventListener } from '../../types/run/events.js'
31
+ import type { SubSessionId } from '../../types/session/ids.js'
32
+ import type { SessionStore } from '../../types/session/store.js'
19
33
  import { createChildAbortController } from '../../utils/abort.js'
20
34
  import { ZERO_COST } from '../../utils/cost.js'
21
35
  import { toErrorMessage } from '../../utils/error.js'
22
36
  import { generateTaskId } from '../../utils/id.js'
23
37
  import { type Logger, getRootLogger } from '../../utils/logger.js'
24
38
 
39
+ /**
40
+ * Dependencies threaded into {@link AgentManager}. Phase 6 promoted the
41
+ * SubSession + Session + WorkspaceRef triple to mandatory spawn primitives —
42
+ * these collaborators replace the old `Object.assign({sourceAgentId,
43
+ * parentTaskId})` loose-cast cadence with a typed {@link Lineage} +
44
+ * {@link SessionSummaryMaterializer} closure of the parent→child message gap.
45
+ *
46
+ * Phase 9 Known Delta #5: fields are now unconditional required. The legacy
47
+ * "run without deps" compat branch was removed; every `AgentManager` consumer
48
+ * (SDK internals, `@namzu/agents`, `@namzu/api`, `@namzu/cli`) MUST wire the
49
+ * full set before instantiating. Convention #0 (no workarounds): the
50
+ * partially-wired mode was a migration-window bridge; 0.2.0 closes it.
51
+ *
52
+ * `workspaceRegistry` is required but may be empty — spawns without a
53
+ * registered workspace backend still succeed with `workspaceRef: undefined`
54
+ * (the runtime uses `.has(backend)` to gate provisioning). This keeps the
55
+ * registry deny-by-default while matching pattern doc §7.1 (lazy workspace
56
+ * provisioning).
57
+ */
58
+ export interface AgentManagerDeps {
59
+ readonly sessionStore: SessionStore
60
+ readonly workspaceRegistry: WorkspaceBackendRegistry
61
+ readonly summaryMaterializer: SessionSummaryMaterializer
62
+ readonly capacity: CapacityValidator
63
+ }
64
+
65
+ interface ChildSpawnRecord {
66
+ subSessionId: SubSessionId
67
+ childSessionId: SessionId
68
+ tenantId: TenantId
69
+ parentSessionId: SessionId
70
+ rootSessionId: SessionId
71
+ childDepth: number
72
+ workspaceRef?: WorkspaceRef
73
+ }
74
+
25
75
  export class AgentManager {
26
76
  private registry: AgentRegistry
27
77
  private instances: Map<TaskId, AgentTask> = new Map()
78
+ private spawnRecords: Map<TaskId, ChildSpawnRecord> = new Map()
28
79
  private completionCallbacks: Map<TaskId, Array<() => void>> = new Map()
29
80
  private listeners: AgentLifecycleListener[] = []
30
81
  private log: Logger
31
82
  private config: Readonly<AgentManagerConfig>
32
83
  private evictionTimers: Map<TaskId, ReturnType<typeof setTimeout>> = new Map()
84
+ private deps: AgentManagerDeps
33
85
 
34
- constructor(registry: AgentRegistry, config?: Partial<AgentManagerConfig>) {
86
+ constructor(
87
+ registry: AgentRegistry,
88
+ config: Partial<AgentManagerConfig> | undefined,
89
+ deps: AgentManagerDeps,
90
+ ) {
35
91
  this.registry = registry
36
92
  this.config = { ...AGENT_MANAGER_DEFAULTS, ...config }
37
93
  this.log = getRootLogger().child({ component: 'AgentManager' })
94
+ this.deps = deps
38
95
  }
39
96
 
40
97
  async sendMessage(
41
98
  options: SendMessageOptions,
42
99
  context: AgentTaskContext,
43
- listener?: import('../../types/run/events.js').RunEventListener,
100
+ listener?: RunEventListener,
44
101
  ): Promise<AgentTask> {
45
102
  if (context.depth >= this.config.maxDepth) {
46
103
  throw new Error(
@@ -48,6 +105,12 @@ export class AgentManager {
48
105
  )
49
106
  }
50
107
 
108
+ if (options.tenantId !== context.tenantId) {
109
+ throw new Error(
110
+ `Tenant mismatch: options.tenantId=${options.tenantId} differs from context.tenantId=${context.tenantId}. Cross-tenant spawn rejected (Convention #17).`,
111
+ )
112
+ }
113
+
51
114
  const agent = this.registry.resolve(options.agentId)
52
115
 
53
116
  const childAbortController = createChildAbortController(context.parentAbortController)
@@ -61,13 +124,39 @@ export class AgentManager {
61
124
  )
62
125
  context.budgetTracker.remaining -= allocatedTokens
63
126
 
127
+ // Phase 6: SubSession + child Session + WorkspaceRef triple. Happens
128
+ // before taskId minting so a capacity failure short-circuits cleanly
129
+ // with no observable state change.
130
+ const spawnRecord = await this.provisionSpawn(options, context)
131
+
64
132
  const taskId = generateTaskId()
133
+
134
+ const childParentActor: ActorRef = {
135
+ kind: 'agent',
136
+ agentId: context.parentAgentId as AgentId,
137
+ tenantId: context.tenantId,
138
+ parentActor: context.parentActor,
139
+ }
140
+
141
+ const childContext: AgentTaskContext = {
142
+ parentRunId: context.parentRunId,
143
+ parentAgentId: context.parentAgentId,
144
+ parentAbortController: context.parentAbortController,
145
+ depth: context.depth + 1,
146
+ budgetTracker: context.budgetTracker,
147
+ factoryOptions: context.factoryOptions,
148
+ tenantId: context.tenantId,
149
+ sessionId: spawnRecord.childSessionId,
150
+ projectId: context.projectId,
151
+ parentActor: childParentActor,
152
+ }
153
+
65
154
  const agentTask: AgentTask = {
66
155
  taskId,
67
156
  agentId: options.agentId,
68
157
  agent,
69
158
  childAbortController,
70
- context,
159
+ context: childContext,
71
160
  state: 'pending',
72
161
  pendingMessages: [],
73
162
  createdAt: Date.now(),
@@ -75,6 +164,7 @@ export class AgentManager {
75
164
  }
76
165
 
77
166
  this.instances.set(taskId, agentTask)
167
+ this.spawnRecords.set(taskId, spawnRecord)
78
168
  this.emit({
79
169
  type: 'pending',
80
170
  taskId,
@@ -92,6 +182,22 @@ export class AgentManager {
92
182
  childAgentId: options.agentId,
93
183
  depth: context.depth,
94
184
  })
185
+
186
+ const lineage: Lineage = {
187
+ parentSessionId: spawnRecord.parentSessionId,
188
+ rootSessionId: spawnRecord.rootSessionId,
189
+ depth: spawnRecord.childDepth,
190
+ }
191
+ listener({
192
+ type: 'subsession_spawned',
193
+ runId: context.parentRunId,
194
+ subSessionId: spawnRecord.subSessionId,
195
+ parentSessionId: spawnRecord.parentSessionId,
196
+ spawnedBy: context.parentActor,
197
+ lineage,
198
+ schemaVersion: RUN_EVENT_SCHEMA_VERSION,
199
+ at: new Date(),
200
+ })
95
201
  }
96
202
  this.log.info(`Agent task pending: ${taskId} (${options.agentId}, depth=${context.depth})`)
97
203
 
@@ -102,7 +208,7 @@ export class AgentManager {
102
208
  ...context.factoryOptions,
103
209
  tokenBudget: allocatedTokens,
104
210
  timeoutMs: options.budgetAllocation?.timeoutMs ?? context.budgetTracker.remaining,
105
- threadId: context.threadId as string | undefined,
211
+ threadId: context.projectId as string,
106
212
  parentRunId: context.parentRunId as string | undefined,
107
213
  depth: context.depth + 1,
108
214
  ...options.configOverrides,
@@ -111,6 +217,13 @@ export class AgentManager {
111
217
  if (!childConfig.contextLevel && definition.contextLevel) {
112
218
  childConfig.contextLevel = definition.contextLevel
113
219
  }
220
+
221
+ // Propagate session-hierarchy scoping onto the child config. The
222
+ // configBuilder may not have been updated to emit these yet; we
223
+ // stamp them here so query() sees them regardless.
224
+ childConfig.sessionId = spawnRecord?.childSessionId ?? context.sessionId
225
+ childConfig.projectId = context.projectId
226
+ childConfig.tenantId = context.tenantId
114
227
  } else {
115
228
  this.log.warn('No configBuilder or factoryOptions, using bare config', {
116
229
  agentId: options.agentId,
@@ -123,7 +236,10 @@ export class AgentManager {
123
236
  maxIterations: options.configOverrides?.maxIterations,
124
237
  maxResponseTokens: options.configOverrides?.maxResponseTokens,
125
238
  env: options.configOverrides?.env,
126
- threadId: context.threadId,
239
+ threadId: context.projectId,
240
+ sessionId: spawnRecord.childSessionId,
241
+ projectId: context.projectId,
242
+ tenantId: context.tenantId,
127
243
  parentRunId: context.parentRunId,
128
244
  depth: context.depth + 1,
129
245
  }
@@ -193,6 +309,10 @@ export class AgentManager {
193
309
  return this.instances.get(taskId)
194
310
  }
195
311
 
312
+ getSpawnRecord(taskId: TaskId): ChildSpawnRecord | undefined {
313
+ return this.spawnRecords.get(taskId)
314
+ }
315
+
196
316
  listByParent(parentRunId: RunId): AgentTask[] {
197
317
  return Array.from(this.instances.values()).filter((t) => t.context.parentRunId === parentRunId)
198
318
  }
@@ -223,6 +343,7 @@ export class AgentManager {
223
343
  if (isTerminalAgentTaskState(agentTask.state)) {
224
344
  this.clearEvictionTimer(taskId)
225
345
  this.instances.delete(taskId)
346
+ this.spawnRecords.delete(taskId)
226
347
  }
227
348
  }
228
349
  }
@@ -233,14 +354,110 @@ export class AgentManager {
233
354
  }
234
355
  this.cancelAll('' as RunId)
235
356
  this.instances.clear()
357
+ this.spawnRecords.clear()
236
358
  this.listeners.length = 0
237
359
  }
238
360
 
361
+ private async provisionSpawn(
362
+ options: SendMessageOptions,
363
+ context: AgentTaskContext,
364
+ ): Promise<ChildSpawnRecord> {
365
+ // Phase 9: deps are unconditional required. Every spawn produces a
366
+ // SubSession + Session + WorkspaceRef triple (Convention #0: no
367
+ // partial/legacy path).
368
+ const store = this.deps.sessionStore
369
+
370
+ const project = await store.getProject(context.projectId, context.tenantId)
371
+ if (!project) {
372
+ throw new Error(
373
+ `Project ${context.projectId} not found for tenant ${context.tenantId} — spawn rejected`,
374
+ )
375
+ }
376
+
377
+ // Capacity: depth + width. Depth uses the parent session's ancestry
378
+ // chain; width counts existing direct children of the parent.
379
+ await this.deps.capacity.validateDepth(
380
+ options.parentSessionId,
381
+ project.config.maxDelegationDepth,
382
+ context.tenantId,
383
+ )
384
+ await this.deps.capacity.validateWidth(
385
+ options.parentSessionId,
386
+ 1,
387
+ project.config.maxDelegationWidth,
388
+ context.tenantId,
389
+ )
390
+
391
+ // Ancestry walk gives both the child depth and the root session id
392
+ // attached to every sub-session event from here down.
393
+ const parentAncestry = await store.getAncestry(options.parentSessionId, context.tenantId)
394
+ const rootSessionId = parentAncestry[0] ?? options.parentSessionId
395
+ const childDepth = parentAncestry.length
396
+
397
+ const childActor: ActorRef = {
398
+ kind: 'agent',
399
+ agentId: options.agentId as AgentId,
400
+ tenantId: context.tenantId,
401
+ parentActor: context.parentActor,
402
+ }
403
+
404
+ const childSession = await store.createSession(
405
+ { projectId: context.projectId, currentActor: childActor },
406
+ context.tenantId,
407
+ )
408
+
409
+ // Flip to 'active' so the materializer's atomic write + status flip
410
+ // lands on terminal — §5.3: pending→active→idle.
411
+ await store.updateSession({ ...childSession, status: 'active' }, context.tenantId)
412
+
413
+ const subSession = await store.createSubSession(
414
+ {
415
+ parentSessionId: options.parentSessionId,
416
+ childSessionId: childSession.id,
417
+ kind: 'agent_spawn',
418
+ spawnedBy: context.parentActor,
419
+ failureMode: 'delegate',
420
+ completionMode: 'summary_ref',
421
+ },
422
+ context.tenantId,
423
+ )
424
+
425
+ // Workspace provisioning — best-effort. When the requested backend is
426
+ // registered we create a new workspace for the child; failures surface
427
+ // as WorkspaceBackendError and abort the spawn (Convention #0: no
428
+ // silent fallback). Pattern doc §7.1 allows lazy provisioning: an
429
+ // unregistered backend leaves `workspaceRef: undefined` on the spawn
430
+ // record, not a hard error — the registry is the capability surface.
431
+ let workspaceRef: WorkspaceRef | undefined
432
+ const backend = options.workspaceBackend ?? 'git-worktree'
433
+ if (this.deps.workspaceRegistry.has(backend)) {
434
+ const driver = this.deps.workspaceRegistry.get(backend)
435
+ try {
436
+ workspaceRef = await driver.create({ label: subSession.id })
437
+ } catch (err) {
438
+ // Surface the failure — the subsession record exists but is
439
+ // unusable without a workspace. Dispose any partial state.
440
+ await store.updateSubSession({ ...subSession, status: 'failed' }, context.tenantId)
441
+ throw err
442
+ }
443
+ }
444
+
445
+ return {
446
+ subSessionId: subSession.id,
447
+ childSessionId: childSession.id,
448
+ tenantId: context.tenantId,
449
+ parentSessionId: options.parentSessionId,
450
+ rootSessionId,
451
+ childDepth,
452
+ workspaceRef,
453
+ }
454
+ }
455
+
239
456
  private async runChild(
240
457
  agentTask: AgentTask,
241
458
  options: SendMessageOptions,
242
459
  childConfig: BaseAgentConfig,
243
- listener?: import('../../types/run/events.js').RunEventListener,
460
+ listener?: RunEventListener,
244
461
  ): Promise<void> {
245
462
  this.updateState(agentTask.taskId, 'running')
246
463
  this.emit({ type: 'running', taskId: agentTask.taskId })
@@ -250,17 +467,135 @@ export class AgentManager {
250
467
  signal: agentTask.childAbortController.signal,
251
468
  }
252
469
 
253
- const childListener = listener
254
- ? async (event: import('../../types/run/events.js').RunEvent): Promise<void> => {
255
- const annotated = Object.assign({}, event, {
256
- sourceAgentId: agentTask.agentId,
257
- parentTaskId: agentTask.taskId,
470
+ const spawnRecord = this.spawnRecords.get(agentTask.taskId)
471
+ const childListener = this.wrapChildListener(listener, spawnRecord)
472
+
473
+ const result = await agentTask.agent.run(input, childConfig, childListener)
474
+ await this.finalizeChild(agentTask, result)
475
+ }
476
+
477
+ /**
478
+ * Wraps the parent listener so every event emitted from the child's run
479
+ * carries the session-hierarchy `lineage` + `schemaVersion: 2` stamp.
480
+ * Replaces the old `Object.assign({sourceAgentId, parentTaskId}, event)`
481
+ * loose-cast pattern entirely — the types now encode the linkage.
482
+ */
483
+ private wrapChildListener(
484
+ listener: RunEventListener | undefined,
485
+ spawnRecord: ChildSpawnRecord | undefined,
486
+ ): RunEventListener | undefined {
487
+ if (!listener) return undefined
488
+ if (!spawnRecord) return listener
489
+
490
+ const lineage: Lineage = {
491
+ parentSessionId: spawnRecord.parentSessionId,
492
+ rootSessionId: spawnRecord.rootSessionId,
493
+ depth: spawnRecord.childDepth,
494
+ }
495
+
496
+ return async (event: RunEvent): Promise<void> => {
497
+ const stamped: RunEvent = {
498
+ ...(event as RunEvent),
499
+ lineage,
500
+ schemaVersion: RUN_EVENT_SCHEMA_VERSION,
501
+ } as RunEvent
502
+ await listener(stamped)
503
+ }
504
+ }
505
+
506
+ private async finalizeChild(agentTask: AgentTask, result: BaseAgentResult): Promise<void> {
507
+ const spawnRecord = this.spawnRecords.get(agentTask.taskId)
508
+
509
+ // Kernel terminalization (§8.1): Materializer seals the summary and
510
+ // atomically flips the child session active→idle. Only run when the
511
+ // child actually succeeded; failed sub-sessions skip materialization
512
+ // and transition the sub-session record to 'failed' (§5.5).
513
+ if (spawnRecord) {
514
+ const store = this.deps.sessionStore
515
+ try {
516
+ if (result.status === 'completed') {
517
+ const outcome: SessionSummaryOutcome = deriveOutcome(result)
518
+ const agentSummary = deriveAgentSummary(result)
519
+ const summary = await this.deps.summaryMaterializer.materialize({
520
+ sessionId: spawnRecord.childSessionId,
521
+ tenantId: spawnRecord.tenantId,
522
+ finalOutcome: outcome,
523
+ agentSummary,
524
+ declaredDeliverables: [],
525
+ keyDecisions: [],
258
526
  })
259
- await listener(annotated as import('../../types/run/events.js').RunEvent)
527
+
528
+ const subSession = await store.getSubSession(
529
+ spawnRecord.subSessionId,
530
+ spawnRecord.tenantId,
531
+ )
532
+ if (subSession) {
533
+ await store.updateSubSession(
534
+ { ...subSession, status: 'idle', summaryRef: summary.id },
535
+ spawnRecord.tenantId,
536
+ )
537
+ }
538
+ } else {
539
+ // Non-success: mark sub-session failed and, when we own a
540
+ // workspace, dispose it. Dispose errors are logged but not
541
+ // propagated — the sub-session state is already persisted.
542
+ const subSession = await store.getSubSession(
543
+ spawnRecord.subSessionId,
544
+ spawnRecord.tenantId,
545
+ )
546
+ if (subSession) {
547
+ await store.updateSubSession({ ...subSession, status: 'failed' }, spawnRecord.tenantId)
548
+ }
549
+ if (spawnRecord.workspaceRef) {
550
+ const backend = spawnRecord.workspaceRef.meta.backend
551
+ if (this.deps.workspaceRegistry.has(backend)) {
552
+ await this.deps.workspaceRegistry
553
+ .get(backend)
554
+ .dispose(spawnRecord.workspaceRef)
555
+ .catch((disposeErr) => {
556
+ this.log.warn('Workspace dispose failed', {
557
+ backend,
558
+ error: toErrorMessage(disposeErr),
559
+ })
560
+ })
561
+ }
562
+ }
260
563
  }
261
- : undefined
564
+ } catch (err) {
565
+ this.log.error('Sub-session finalization failed', {
566
+ taskId: agentTask.taskId,
567
+ error: toErrorMessage(err),
568
+ })
569
+ }
570
+ }
571
+
572
+ // Emit subsession_idled event on success before marking the task
573
+ // completed — consumers expect the ordering `run_completed (child) →
574
+ // subsession_idled → run_completed (parent)` per §10.5.
575
+ if (spawnRecord && agentTask.runEventListener && result.status === 'completed') {
576
+ const lineage: Lineage = {
577
+ parentSessionId: spawnRecord.parentSessionId,
578
+ rootSessionId: spawnRecord.rootSessionId,
579
+ depth: spawnRecord.childDepth,
580
+ }
581
+ try {
582
+ await agentTask.runEventListener({
583
+ type: 'subsession_idled',
584
+ runId: agentTask.context.parentRunId,
585
+ subSessionId: spawnRecord.subSessionId,
586
+ parentSessionId: spawnRecord.parentSessionId,
587
+ lineage,
588
+ schemaVersion: RUN_EVENT_SCHEMA_VERSION,
589
+ at: new Date(),
590
+ })
591
+ } catch (err) {
592
+ this.log.error('subsession_idled emission error', {
593
+ taskId: agentTask.taskId,
594
+ error: toErrorMessage(err),
595
+ })
596
+ }
597
+ }
262
598
 
263
- const result = await agentTask.agent.run(input, childConfig, childListener)
264
599
  this.markCompleted(agentTask.taskId, result)
265
600
  }
266
601
 
@@ -307,10 +642,45 @@ export class AgentManager {
307
642
  error,
308
643
  })
309
644
  this.log.error(`Agent task failed: ${taskId}`, { error })
645
+
646
+ // Best-effort: mark sub-session failed + dispose workspace. The result
647
+ // emission path already synthesized a failure result above.
648
+ const spawnRecord = this.spawnRecords.get(taskId)
649
+ if (spawnRecord) {
650
+ this.failSubSession(spawnRecord).catch((err) => {
651
+ this.log.warn('SubSession failure update failed', {
652
+ taskId,
653
+ error: toErrorMessage(err),
654
+ })
655
+ })
656
+ }
657
+
310
658
  this.scheduleEviction(taskId)
311
659
  this.resolveCompletionCallbacks(taskId)
312
660
  }
313
661
 
662
+ private async failSubSession(spawnRecord: ChildSpawnRecord): Promise<void> {
663
+ const subSession = await this.deps.sessionStore.getSubSession(
664
+ spawnRecord.subSessionId,
665
+ spawnRecord.tenantId,
666
+ )
667
+ if (subSession && subSession.status !== 'failed') {
668
+ await this.deps.sessionStore.updateSubSession(
669
+ { ...subSession, status: 'failed' },
670
+ spawnRecord.tenantId,
671
+ )
672
+ }
673
+ if (spawnRecord.workspaceRef) {
674
+ const backend = spawnRecord.workspaceRef.meta.backend
675
+ if (this.deps.workspaceRegistry.has(backend)) {
676
+ await this.deps.workspaceRegistry
677
+ .get(backend)
678
+ .dispose(spawnRecord.workspaceRef)
679
+ .catch(() => undefined)
680
+ }
681
+ }
682
+ }
683
+
314
684
  private markCanceled(taskId: TaskId): void {
315
685
  const agentTask = this.instances.get(taskId)
316
686
  if (!agentTask || isTerminalAgentTaskState(agentTask.state)) return
@@ -351,6 +721,7 @@ export class AgentManager {
351
721
 
352
722
  const timer = setTimeout(() => {
353
723
  this.instances.delete(taskId)
724
+ this.spawnRecords.delete(taskId)
354
725
  this.evictionTimers.delete(taskId)
355
726
  this.log.info(`Agent task evicted: ${taskId}`)
356
727
  }, this.config.evictionMs)
@@ -387,10 +758,7 @@ export class AgentManager {
387
758
  }
388
759
  }
389
760
 
390
- private emitRunEvent(
391
- agentTask: AgentTask,
392
- event: import('../../types/run/events.js').RunEvent,
393
- ): void {
761
+ private emitRunEvent(agentTask: AgentTask, event: RunEvent): void {
394
762
  if (!agentTask.runEventListener) return
395
763
  try {
396
764
  agentTask.runEventListener(event)
@@ -403,3 +771,50 @@ export class AgentManager {
403
771
  }
404
772
  }
405
773
  }
774
+
775
+ /**
776
+ * Maps a {@link BaseAgentResult} to {@link SessionSummaryOutcome}. Phase 6
777
+ * INTERPRETATION: `completed` → `succeeded`; any other status → `failed`.
778
+ * A dedicated `partial` signal requires structured-output contracts on the
779
+ * child's terminal turn (§8.1) which lands in a later phase.
780
+ */
781
+ function deriveOutcome(result: BaseAgentResult): SessionSummaryOutcome {
782
+ if (result.status === 'completed') {
783
+ return { status: 'succeeded' }
784
+ }
785
+ const verdict = result.lastError ?? String(result.status)
786
+ return { status: 'failed', verdict }
787
+ }
788
+
789
+ const SUMMARY_FALLBACK_MAX_CHARS = 4000
790
+
791
+ /**
792
+ * Pulls the agent's own narration from the final assistant message. §8.1:
793
+ * agents may register a structured-output contract for this; when absent
794
+ * we fall back to the last text block. Bounded by the summary char cap so
795
+ * the materializer never rejects on length at this seam.
796
+ */
797
+ function deriveAgentSummary(result: BaseAgentResult): string {
798
+ const fromResult = result.result?.trim()
799
+ if (fromResult) {
800
+ return fromResult.length > SUMMARY_FALLBACK_MAX_CHARS
801
+ ? fromResult.slice(0, SUMMARY_FALLBACK_MAX_CHARS)
802
+ : fromResult
803
+ }
804
+ for (let i = result.messages.length - 1; i >= 0; i--) {
805
+ const msg = result.messages[i]
806
+ if (msg?.role === 'assistant') {
807
+ const content = typeof msg.content === 'string' ? msg.content : ''
808
+ if (content.trim().length > 0) {
809
+ return content.length > SUMMARY_FALLBACK_MAX_CHARS
810
+ ? content.slice(0, SUMMARY_FALLBACK_MAX_CHARS)
811
+ : content
812
+ }
813
+ }
814
+ }
815
+ return ''
816
+ }
817
+
818
+ // Re-export the capacity-violation type so downstream consumers that import
819
+ // via the AgentManager module surface don't reach into session/handoff/.
820
+ export { DelegationCapacityExceeded }
@@ -1,10 +1,11 @@
1
1
  import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js'
2
2
  import { RunDiskStore } from '../../store/run/disk.js'
3
3
  import { type CostInfo, type TokenUsage, accumulateTokenUsage } from '../../types/common/index.js'
4
- import type { RunId } from '../../types/ids/index.js'
4
+ import type { RunId, SessionId, TenantId } from '../../types/ids/index.js'
5
5
  import type { AssistantMessage, Message } from '../../types/message/index.js'
6
6
  import type { EmergencySaveData } from '../../types/run/emergency.js'
7
7
  import type { AgentRun, RunPersistenceConfig, StopReason } from '../../types/run/index.js'
8
+ import type { ProjectId } from '../../types/session/ids.js'
8
9
  import { type ModelPricing, ZERO_COST, accumulateCost } from '../../utils/cost.js'
9
10
  import { generateEmergencySaveId } from '../../utils/id.js'
10
11
  import type { Logger } from '../../utils/logger.js'
@@ -14,10 +15,16 @@ export class RunPersistence {
14
15
  private runStore: RunDiskStore
15
16
  private pricing?: ModelPricing
16
17
  private log: Logger
18
+ private readonly _sessionId: SessionId
19
+ private readonly _tenantId: TenantId
20
+ private readonly _projectId: ProjectId
17
21
 
18
22
  constructor(config: RunPersistenceConfig) {
19
23
  this.pricing = config.pricing
20
24
  this.log = config.log
25
+ this._sessionId = config.sessionId
26
+ this._tenantId = config.tenantId
27
+ this._projectId = config.projectId
21
28
 
22
29
  this.runStore = new RunDiskStore({
23
30
  baseDir: config.outputDir,
@@ -47,6 +54,18 @@ export class RunPersistence {
47
54
  return this.run.id
48
55
  }
49
56
 
57
+ get sessionId(): SessionId {
58
+ return this._sessionId
59
+ }
60
+
61
+ get tenantId(): TenantId {
62
+ return this._tenantId
63
+ }
64
+
65
+ get projectId(): ProjectId {
66
+ return this._projectId
67
+ }
68
+
50
69
  get status() {
51
70
  return this.run.status
52
71
  }
@@ -194,6 +194,34 @@ export function createRunReporter(parentLogger?: Logger): RunReporter {
194
194
  })
195
195
  break
196
196
 
197
+ case 'subsession_spawned':
198
+ log.debug('Sub-session spawned', {
199
+ runId: event.runId,
200
+ subSessionId: event.subSessionId,
201
+ parentSessionId: event.parentSessionId,
202
+ depth: event.lineage.depth,
203
+ })
204
+ break
205
+
206
+ case 'subsession_messaged':
207
+ log.debug('Sub-session message', {
208
+ runId: event.runId,
209
+ subSessionId: event.subSessionId,
210
+ parentSessionId: event.parentSessionId,
211
+ messageId: event.messageId,
212
+ depth: event.lineage.depth,
213
+ })
214
+ break
215
+
216
+ case 'subsession_idled':
217
+ log.debug('Sub-session idled', {
218
+ runId: event.runId,
219
+ subSessionId: event.subSessionId,
220
+ parentSessionId: event.parentSessionId,
221
+ depth: event.lineage.depth,
222
+ })
223
+ break
224
+
197
225
  default: {
198
226
  const _exhaustive: never = event
199
227
  throw new Error(`Unhandled run event type: ${(_exhaustive as RunEvent).type}`)