@namzu/sdk 0.1.8 → 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 (531) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  3. package/dist/agents/ReactiveAgent.js +5 -3
  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 +18 -5
  10. package/dist/agents/SupervisorAgent.js.map +1 -1
  11. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  12. package/dist/bridge/a2a/mapper.js +6 -0
  13. package/dist/bridge/a2a/mapper.js.map +1 -1
  14. package/dist/bridge/a2a/task.d.ts +2 -2
  15. package/dist/bridge/a2a/task.d.ts.map +1 -1
  16. package/dist/bridge/a2a/task.js.map +1 -1
  17. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  18. package/dist/bridge/sse/mapper.js +6 -0
  19. package/dist/bridge/sse/mapper.js.map +1 -1
  20. package/dist/constants/a2a/index.d.ts +2 -2
  21. package/dist/constants/a2a/index.d.ts.map +1 -1
  22. package/dist/constants/a2a/index.js.map +1 -1
  23. package/dist/contracts/api.d.ts +22 -3
  24. package/dist/contracts/api.d.ts.map +1 -1
  25. package/dist/contracts/index.d.ts +3 -1
  26. package/dist/contracts/index.d.ts.map +1 -1
  27. package/dist/contracts/index.js.map +1 -1
  28. package/dist/gateway/local.d.ts.map +1 -1
  29. package/dist/gateway/local.js +6 -0
  30. package/dist/gateway/local.js.map +1 -1
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +4 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
  36. package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
  37. package/dist/manager/agent/__tests__/lifecycle.test.js +302 -0
  38. package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
  39. package/dist/manager/agent/lifecycle.d.ts +58 -3
  40. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  41. package/dist/manager/agent/lifecycle.js +311 -12
  42. package/dist/manager/agent/lifecycle.js.map +1 -1
  43. package/dist/manager/run/persistence.d.ts +8 -1
  44. package/dist/manager/run/persistence.d.ts.map +1 -1
  45. package/dist/manager/run/persistence.js +15 -0
  46. package/dist/manager/run/persistence.js.map +1 -1
  47. package/dist/run/reporter.d.ts.map +1 -1
  48. package/dist/run/reporter.js +25 -0
  49. package/dist/run/reporter.js.map +1 -1
  50. package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
  51. package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
  52. package/dist/runtime/query/__tests__/context.test.js +84 -0
  53. package/dist/runtime/query/__tests__/context.test.js.map +1 -0
  54. package/dist/runtime/query/context.d.ts +55 -2
  55. package/dist/runtime/query/context.d.ts.map +1 -1
  56. package/dist/runtime/query/context.js +48 -8
  57. package/dist/runtime/query/context.js.map +1 -1
  58. package/dist/runtime/query/events.d.ts.map +1 -1
  59. package/dist/runtime/query/events.js +8 -0
  60. package/dist/runtime/query/events.js.map +1 -1
  61. package/dist/runtime/query/index.d.ts +25 -2
  62. package/dist/runtime/query/index.d.ts.map +1 -1
  63. package/dist/runtime/query/index.js +11 -1
  64. package/dist/runtime/query/index.js.map +1 -1
  65. package/dist/session/__tests__/integration/_fixtures.d.ts +115 -0
  66. package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
  67. package/dist/session/__tests__/integration/_fixtures.js +198 -0
  68. package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
  69. package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
  70. package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
  71. package/dist/session/__tests__/integration/capacity-caps.test.js +116 -0
  72. package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
  73. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
  74. package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
  75. package/dist/session/__tests__/integration/e2e-spawn.test.js +226 -0
  76. package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
  77. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
  78. package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
  79. package/dist/session/__tests__/integration/event-stream-ordering.test.js +323 -0
  80. package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
  81. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
  82. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
  83. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +170 -0
  84. package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
  85. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
  86. package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
  87. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +146 -0
  88. package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
  89. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
  90. package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
  91. package/dist/session/__tests__/integration/handoff-single-e2e.test.js +163 -0
  92. package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
  93. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
  94. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
  95. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +157 -0
  96. package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
  97. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
  98. package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
  99. package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
  100. package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
  101. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
  102. package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
  103. package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
  104. package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
  105. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
  106. package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
  107. package/dist/session/__tests__/integration/prev-artifact-dag.test.js +241 -0
  108. package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
  109. package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
  110. package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
  111. package/dist/session/__tests__/integration/retention-archive.test.js +186 -0
  112. package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
  113. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
  114. package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
  115. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +200 -0
  116. package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
  117. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
  118. package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
  119. package/dist/session/__tests__/integration/tenant-isolation.test.js +180 -0
  120. package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
  121. package/dist/session/errors.d.ts +60 -0
  122. package/dist/session/errors.d.ts.map +1 -0
  123. package/dist/session/errors.js +50 -0
  124. package/dist/session/errors.js.map +1 -0
  125. package/dist/session/events/index.d.ts +4 -0
  126. package/dist/session/events/index.d.ts.map +1 -0
  127. package/dist/session/events/index.js +8 -0
  128. package/dist/session/events/index.js.map +1 -0
  129. package/dist/session/events/schema-version.d.ts +13 -0
  130. package/dist/session/events/schema-version.d.ts.map +1 -0
  131. package/dist/session/events/schema-version.js +12 -0
  132. package/dist/session/events/schema-version.js.map +1 -0
  133. package/dist/session/events/types.d.ts +64 -0
  134. package/dist/session/events/types.d.ts.map +1 -0
  135. package/dist/session/events/types.js +2 -0
  136. package/dist/session/events/types.js.map +1 -0
  137. package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
  138. package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
  139. package/dist/session/handoff/__tests__/broadcast.test.js +243 -0
  140. package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
  141. package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
  142. package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
  143. package/dist/session/handoff/__tests__/capacity.test.js +100 -0
  144. package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
  145. package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
  146. package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
  147. package/dist/session/handoff/__tests__/single.test.js +230 -0
  148. package/dist/session/handoff/__tests__/single.test.js.map +1 -0
  149. package/dist/session/handoff/assignment.d.ts +59 -0
  150. package/dist/session/handoff/assignment.d.ts.map +1 -0
  151. package/dist/session/handoff/assignment.js +11 -0
  152. package/dist/session/handoff/assignment.js.map +1 -0
  153. package/dist/session/handoff/broadcast.d.ts +47 -0
  154. package/dist/session/handoff/broadcast.d.ts.map +1 -0
  155. package/dist/session/handoff/broadcast.js +296 -0
  156. package/dist/session/handoff/broadcast.js.map +1 -0
  157. package/dist/session/handoff/capacity.d.ts +66 -0
  158. package/dist/session/handoff/capacity.d.ts.map +1 -0
  159. package/dist/session/handoff/capacity.js +60 -0
  160. package/dist/session/handoff/capacity.js.map +1 -0
  161. package/dist/session/handoff/events.d.ts +66 -0
  162. package/dist/session/handoff/events.d.ts.map +1 -0
  163. package/dist/session/handoff/events.js +13 -0
  164. package/dist/session/handoff/events.js.map +1 -0
  165. package/dist/session/handoff/index.d.ts +12 -0
  166. package/dist/session/handoff/index.d.ts.map +1 -0
  167. package/dist/session/handoff/index.js +9 -0
  168. package/dist/session/handoff/index.js.map +1 -0
  169. package/dist/session/handoff/single.d.ts +62 -0
  170. package/dist/session/handoff/single.d.ts.map +1 -0
  171. package/dist/session/handoff/single.js +217 -0
  172. package/dist/session/handoff/single.js.map +1 -0
  173. package/dist/session/handoff/version.d.ts +52 -0
  174. package/dist/session/handoff/version.d.ts.map +1 -0
  175. package/dist/session/handoff/version.js +36 -0
  176. package/dist/session/handoff/version.js.map +1 -0
  177. package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
  178. package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
  179. package/dist/session/hierarchy/__tests__/session.test.js +67 -0
  180. package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
  181. package/dist/session/hierarchy/actor.d.ts +26 -0
  182. package/dist/session/hierarchy/actor.d.ts.map +1 -0
  183. package/dist/session/hierarchy/actor.js +2 -0
  184. package/dist/session/hierarchy/actor.js.map +1 -0
  185. package/dist/session/hierarchy/index.d.ts +8 -0
  186. package/dist/session/hierarchy/index.d.ts.map +1 -0
  187. package/dist/session/hierarchy/index.js +4 -0
  188. package/dist/session/hierarchy/index.js.map +1 -0
  189. package/dist/session/hierarchy/lineage.d.ts +15 -0
  190. package/dist/session/hierarchy/lineage.d.ts.map +1 -0
  191. package/dist/session/hierarchy/lineage.js +2 -0
  192. package/dist/session/hierarchy/lineage.js.map +1 -0
  193. package/dist/session/hierarchy/project.d.ts +40 -0
  194. package/dist/session/hierarchy/project.d.ts.map +1 -0
  195. package/dist/session/hierarchy/project.js +2 -0
  196. package/dist/session/hierarchy/project.js.map +1 -0
  197. package/dist/session/hierarchy/session.d.ts +59 -0
  198. package/dist/session/hierarchy/session.d.ts.map +1 -0
  199. package/dist/session/hierarchy/session.js +51 -0
  200. package/dist/session/hierarchy/session.js.map +1 -0
  201. package/dist/session/hierarchy/sub-session.d.ts +76 -0
  202. package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
  203. package/dist/session/hierarchy/sub-session.js +2 -0
  204. package/dist/session/hierarchy/sub-session.js.map +1 -0
  205. package/dist/session/hierarchy/tenant.d.ts +13 -0
  206. package/dist/session/hierarchy/tenant.d.ts.map +1 -0
  207. package/dist/session/hierarchy/tenant.js +2 -0
  208. package/dist/session/hierarchy/tenant.js.map +1 -0
  209. package/dist/session/index.d.ts +10 -0
  210. package/dist/session/index.d.ts.map +1 -0
  211. package/dist/session/index.js +15 -0
  212. package/dist/session/index.js.map +1 -0
  213. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
  214. package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
  215. package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
  216. package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
  217. package/dist/session/intervention/index.d.ts +3 -0
  218. package/dist/session/intervention/index.d.ts.map +1 -0
  219. package/dist/session/intervention/index.js +8 -0
  220. package/dist/session/intervention/index.js.map +1 -0
  221. package/dist/session/intervention/prev-artifact.d.ts +103 -0
  222. package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
  223. package/dist/session/intervention/prev-artifact.js +112 -0
  224. package/dist/session/intervention/prev-artifact.js.map +1 -0
  225. package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
  226. package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
  227. package/dist/session/migration/__tests__/filesystem.test.js +188 -0
  228. package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
  229. package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
  230. package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
  231. package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
  232. package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
  233. package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
  234. package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
  235. package/dist/session/migration/__tests__/marker.test.js +75 -0
  236. package/dist/session/migration/__tests__/marker.test.js.map +1 -0
  237. package/dist/session/migration/errors.d.ts +26 -0
  238. package/dist/session/migration/errors.d.ts.map +1 -0
  239. package/dist/session/migration/errors.js +22 -0
  240. package/dist/session/migration/errors.js.map +1 -0
  241. package/dist/session/migration/filesystem.d.ts +94 -0
  242. package/dist/session/migration/filesystem.d.ts.map +1 -0
  243. package/dist/session/migration/filesystem.js +319 -0
  244. package/dist/session/migration/filesystem.js.map +1 -0
  245. package/dist/session/migration/id-prefix.d.ts +98 -0
  246. package/dist/session/migration/id-prefix.d.ts.map +1 -0
  247. package/dist/session/migration/id-prefix.js +116 -0
  248. package/dist/session/migration/id-prefix.js.map +1 -0
  249. package/dist/session/migration/index.d.ts +8 -0
  250. package/dist/session/migration/index.d.ts.map +1 -0
  251. package/dist/session/migration/index.js +8 -0
  252. package/dist/session/migration/index.js.map +1 -0
  253. package/dist/session/migration/marker.d.ts +57 -0
  254. package/dist/session/migration/marker.d.ts.map +1 -0
  255. package/dist/session/migration/marker.js +111 -0
  256. package/dist/session/migration/marker.js.map +1 -0
  257. package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
  258. package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
  259. package/dist/session/retention/__tests__/archive.test.js +252 -0
  260. package/dist/session/retention/__tests__/archive.test.js.map +1 -0
  261. package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
  262. package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
  263. package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
  264. package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
  265. package/dist/session/retention/archive-backend-ref.d.ts +18 -0
  266. package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
  267. package/dist/session/retention/archive-backend-ref.js +2 -0
  268. package/dist/session/retention/archive-backend-ref.js.map +1 -0
  269. package/dist/session/retention/archive.d.ts +130 -0
  270. package/dist/session/retention/archive.d.ts.map +1 -0
  271. package/dist/session/retention/archive.js +203 -0
  272. package/dist/session/retention/archive.js.map +1 -0
  273. package/dist/session/retention/backend.d.ts +101 -0
  274. package/dist/session/retention/backend.d.ts.map +1 -0
  275. package/dist/session/retention/backend.js +15 -0
  276. package/dist/session/retention/backend.js.map +1 -0
  277. package/dist/session/retention/disk-backend.d.ts +59 -0
  278. package/dist/session/retention/disk-backend.d.ts.map +1 -0
  279. package/dist/session/retention/disk-backend.js +236 -0
  280. package/dist/session/retention/disk-backend.js.map +1 -0
  281. package/dist/session/retention/index.d.ts +9 -0
  282. package/dist/session/retention/index.d.ts.map +1 -0
  283. package/dist/session/retention/index.js +6 -0
  284. package/dist/session/retention/index.js.map +1 -0
  285. package/dist/session/retention/policy.d.ts +49 -0
  286. package/dist/session/retention/policy.d.ts.map +1 -0
  287. package/dist/session/retention/policy.js +21 -0
  288. package/dist/session/retention/policy.js.map +1 -0
  289. package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
  290. package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
  291. package/dist/session/summary/__tests__/materialize.test.js +269 -0
  292. package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
  293. package/dist/session/summary/deliverable.d.ts +74 -0
  294. package/dist/session/summary/deliverable.d.ts.map +1 -0
  295. package/dist/session/summary/deliverable.js +20 -0
  296. package/dist/session/summary/deliverable.js.map +1 -0
  297. package/dist/session/summary/index.d.ts +6 -0
  298. package/dist/session/summary/index.d.ts.map +1 -0
  299. package/dist/session/summary/index.js +9 -0
  300. package/dist/session/summary/index.js.map +1 -0
  301. package/dist/session/summary/materialize.d.ts +82 -0
  302. package/dist/session/summary/materialize.d.ts.map +1 -0
  303. package/dist/session/summary/materialize.js +117 -0
  304. package/dist/session/summary/materialize.js.map +1 -0
  305. package/dist/session/summary/ref.d.ts +91 -0
  306. package/dist/session/summary/ref.d.ts.map +1 -0
  307. package/dist/session/summary/ref.js +51 -0
  308. package/dist/session/summary/ref.js.map +1 -0
  309. package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
  310. package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
  311. package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
  312. package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
  313. package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
  314. package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
  315. package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
  316. package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
  317. package/dist/session/workspace/driver.d.ts +55 -0
  318. package/dist/session/workspace/driver.d.ts.map +1 -0
  319. package/dist/session/workspace/driver.js +12 -0
  320. package/dist/session/workspace/driver.js.map +1 -0
  321. package/dist/session/workspace/git-worktree.d.ts +65 -0
  322. package/dist/session/workspace/git-worktree.d.ts.map +1 -0
  323. package/dist/session/workspace/git-worktree.js +156 -0
  324. package/dist/session/workspace/git-worktree.js.map +1 -0
  325. package/dist/session/workspace/index.d.ts +8 -0
  326. package/dist/session/workspace/index.d.ts.map +1 -0
  327. package/dist/session/workspace/index.js +7 -0
  328. package/dist/session/workspace/index.js.map +1 -0
  329. package/dist/session/workspace/path-builder.d.ts +50 -0
  330. package/dist/session/workspace/path-builder.d.ts.map +1 -0
  331. package/dist/session/workspace/path-builder.js +50 -0
  332. package/dist/session/workspace/path-builder.js.map +1 -0
  333. package/dist/session/workspace/ref.d.ts +46 -0
  334. package/dist/session/workspace/ref.d.ts.map +1 -0
  335. package/dist/session/workspace/ref.js +11 -0
  336. package/dist/session/workspace/ref.js.map +1 -0
  337. package/dist/session/workspace/registry.d.ts +26 -0
  338. package/dist/session/workspace/registry.d.ts.map +1 -0
  339. package/dist/session/workspace/registry.js +35 -0
  340. package/dist/session/workspace/registry.js.map +1 -0
  341. package/dist/store/conversation/memory.d.ts +22 -0
  342. package/dist/store/conversation/memory.d.ts.map +1 -1
  343. package/dist/store/conversation/memory.js +22 -0
  344. package/dist/store/conversation/memory.js.map +1 -1
  345. package/dist/store/session/__tests__/disk.test.d.ts +2 -0
  346. package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
  347. package/dist/store/session/__tests__/disk.test.js +240 -0
  348. package/dist/store/session/__tests__/disk.test.js.map +1 -0
  349. package/dist/store/session/__tests__/memory.test.d.ts +2 -0
  350. package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
  351. package/dist/store/session/__tests__/memory.test.js +217 -0
  352. package/dist/store/session/__tests__/memory.test.js.map +1 -0
  353. package/dist/store/session/disk.d.ts +85 -0
  354. package/dist/store/session/disk.d.ts.map +1 -0
  355. package/dist/store/session/disk.js +757 -0
  356. package/dist/store/session/disk.js.map +1 -0
  357. package/dist/store/session/index.d.ts +7 -0
  358. package/dist/store/session/index.d.ts.map +1 -0
  359. package/dist/store/session/index.js +11 -0
  360. package/dist/store/session/index.js.map +1 -0
  361. package/dist/store/session/linkage.d.ts +38 -0
  362. package/dist/store/session/linkage.d.ts.map +1 -0
  363. package/dist/store/session/linkage.js +64 -0
  364. package/dist/store/session/linkage.js.map +1 -0
  365. package/dist/store/session/memory.d.ts +48 -0
  366. package/dist/store/session/memory.d.ts.map +1 -0
  367. package/dist/store/session/memory.js +322 -0
  368. package/dist/store/session/memory.js.map +1 -0
  369. package/dist/store/session/messages.d.ts +20 -0
  370. package/dist/store/session/messages.d.ts.map +1 -0
  371. package/dist/store/session/messages.js +12 -0
  372. package/dist/store/session/messages.js.map +1 -0
  373. package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
  374. package/dist/types/agent/base.d.ts +28 -1
  375. package/dist/types/agent/base.d.ts.map +1 -1
  376. package/dist/types/agent/task.d.ts +50 -2
  377. package/dist/types/agent/task.d.ts.map +1 -1
  378. package/dist/types/agent/task.js.map +1 -1
  379. package/dist/types/conversation/index.d.ts +7 -0
  380. package/dist/types/conversation/index.d.ts.map +1 -1
  381. package/dist/types/ids/index.d.ts +26 -3
  382. package/dist/types/ids/index.d.ts.map +1 -1
  383. package/dist/types/ids/index.js +8 -1
  384. package/dist/types/ids/index.js.map +1 -1
  385. package/dist/types/invocation/__tests__/state.test.js +36 -29
  386. package/dist/types/invocation/__tests__/state.test.js.map +1 -1
  387. package/dist/types/invocation/index.d.ts +20 -4
  388. package/dist/types/invocation/index.d.ts.map +1 -1
  389. package/dist/types/invocation/index.js +10 -7
  390. package/dist/types/invocation/index.js.map +1 -1
  391. package/dist/types/run/config.d.ts +11 -1
  392. package/dist/types/run/config.d.ts.map +1 -1
  393. package/dist/types/run/events.d.ts +26 -1
  394. package/dist/types/run/events.d.ts.map +1 -1
  395. package/dist/types/run/index.d.ts.map +1 -1
  396. package/dist/types/run/index.js +8 -0
  397. package/dist/types/run/index.js.map +1 -1
  398. package/dist/types/run/metadata.d.ts +24 -1
  399. package/dist/types/run/metadata.d.ts.map +1 -1
  400. package/dist/types/run/status.d.ts +26 -0
  401. package/dist/types/run/status.d.ts.map +1 -0
  402. package/dist/types/run/status.js +2 -0
  403. package/dist/types/run/status.js.map +1 -0
  404. package/dist/types/session/ids.d.ts +18 -0
  405. package/dist/types/session/ids.d.ts.map +1 -0
  406. package/dist/types/session/ids.js +12 -0
  407. package/dist/types/session/ids.js.map +1 -0
  408. package/dist/types/session/index.d.ts +3 -0
  409. package/dist/types/session/index.d.ts.map +1 -0
  410. package/dist/types/session/index.js +5 -0
  411. package/dist/types/session/index.js.map +1 -0
  412. package/dist/types/session/store.d.ts +188 -0
  413. package/dist/types/session/store.d.ts.map +1 -0
  414. package/dist/types/session/store.js +14 -0
  415. package/dist/types/session/store.js.map +1 -0
  416. package/dist/utils/id.d.ts +18 -1
  417. package/dist/utils/id.d.ts.map +1 -1
  418. package/dist/utils/id.js +42 -4
  419. package/dist/utils/id.js.map +1 -1
  420. package/package.json +1 -1
  421. package/src/agents/ReactiveAgent.ts +7 -3
  422. package/src/agents/RouterAgent.ts +5 -0
  423. package/src/agents/SupervisorAgent.ts +26 -6
  424. package/src/bridge/a2a/mapper.ts +7 -0
  425. package/src/bridge/a2a/task.ts +2 -2
  426. package/src/bridge/sse/mapper.ts +8 -1
  427. package/src/constants/a2a/index.ts +2 -2
  428. package/src/contracts/api.ts +23 -3
  429. package/src/contracts/index.ts +2 -0
  430. package/src/gateway/local.ts +6 -0
  431. package/src/index.ts +14 -0
  432. package/src/manager/agent/__tests__/lifecycle.test.ts +452 -0
  433. package/src/manager/agent/lifecycle.ts +434 -19
  434. package/src/manager/run/persistence.ts +20 -1
  435. package/src/run/reporter.ts +28 -0
  436. package/src/runtime/query/__tests__/context.test.ts +101 -0
  437. package/src/runtime/query/context.ts +106 -10
  438. package/src/runtime/query/events.ts +8 -0
  439. package/src/runtime/query/index.ts +41 -3
  440. package/src/session/__tests__/integration/_fixtures.ts +282 -0
  441. package/src/session/__tests__/integration/capacity-caps.test.ts +164 -0
  442. package/src/session/__tests__/integration/e2e-spawn.test.ts +278 -0
  443. package/src/session/__tests__/integration/event-stream-ordering.test.ts +403 -0
  444. package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +245 -0
  445. package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +179 -0
  446. package/src/session/__tests__/integration/handoff-single-e2e.test.ts +220 -0
  447. package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +237 -0
  448. package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
  449. package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
  450. package/src/session/__tests__/integration/prev-artifact-dag.test.ts +318 -0
  451. package/src/session/__tests__/integration/retention-archive.test.ts +231 -0
  452. package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +237 -0
  453. package/src/session/__tests__/integration/tenant-isolation.test.ts +282 -0
  454. package/src/session/errors.ts +70 -0
  455. package/src/session/events/index.ts +16 -0
  456. package/src/session/events/schema-version.ts +13 -0
  457. package/src/session/events/types.ts +71 -0
  458. package/src/session/handoff/__tests__/broadcast.test.ts +350 -0
  459. package/src/session/handoff/__tests__/capacity.test.ts +123 -0
  460. package/src/session/handoff/__tests__/single.test.ts +316 -0
  461. package/src/session/handoff/assignment.ts +62 -0
  462. package/src/session/handoff/broadcast.ts +381 -0
  463. package/src/session/handoff/capacity.ts +121 -0
  464. package/src/session/handoff/events.ts +72 -0
  465. package/src/session/handoff/index.ts +29 -0
  466. package/src/session/handoff/single.ts +288 -0
  467. package/src/session/handoff/version.ts +59 -0
  468. package/src/session/hierarchy/__tests__/session.test.ts +92 -0
  469. package/src/session/hierarchy/actor.ts +17 -0
  470. package/src/session/hierarchy/index.ts +17 -0
  471. package/src/session/hierarchy/lineage.ts +15 -0
  472. package/src/session/hierarchy/project.ts +41 -0
  473. package/src/session/hierarchy/session.ts +97 -0
  474. package/src/session/hierarchy/sub-session.ts +92 -0
  475. package/src/session/hierarchy/tenant.ts +13 -0
  476. package/src/session/index.ts +15 -0
  477. package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
  478. package/src/session/intervention/index.ts +16 -0
  479. package/src/session/intervention/prev-artifact.ts +180 -0
  480. package/src/session/migration/__tests__/filesystem.test.ts +263 -0
  481. package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
  482. package/src/session/migration/__tests__/marker.test.ts +84 -0
  483. package/src/session/migration/errors.ts +23 -0
  484. package/src/session/migration/filesystem.ts +401 -0
  485. package/src/session/migration/id-prefix.ts +146 -0
  486. package/src/session/migration/index.ts +38 -0
  487. package/src/session/migration/marker.ts +131 -0
  488. package/src/session/retention/__tests__/archive.test.ts +316 -0
  489. package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
  490. package/src/session/retention/archive-backend-ref.ts +17 -0
  491. package/src/session/retention/archive.ts +281 -0
  492. package/src/session/retention/backend.ts +107 -0
  493. package/src/session/retention/disk-backend.ts +304 -0
  494. package/src/session/retention/index.ts +16 -0
  495. package/src/session/retention/policy.ts +53 -0
  496. package/src/session/summary/__tests__/materialize.test.ts +341 -0
  497. package/src/session/summary/deliverable.ts +84 -0
  498. package/src/session/summary/index.ts +31 -0
  499. package/src/session/summary/materialize.ts +169 -0
  500. package/src/session/summary/ref.ts +104 -0
  501. package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
  502. package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
  503. package/src/session/workspace/driver.ts +60 -0
  504. package/src/session/workspace/git-worktree.ts +209 -0
  505. package/src/session/workspace/index.ts +25 -0
  506. package/src/session/workspace/path-builder.ts +71 -0
  507. package/src/session/workspace/ref.ts +50 -0
  508. package/src/session/workspace/registry.ts +42 -0
  509. package/src/store/conversation/memory.ts +23 -0
  510. package/src/store/session/__tests__/disk.test.ts +346 -0
  511. package/src/store/session/__tests__/memory.test.ts +327 -0
  512. package/src/store/session/disk.ts +920 -0
  513. package/src/store/session/index.ts +14 -0
  514. package/src/store/session/linkage.ts +80 -0
  515. package/src/store/session/memory.ts +400 -0
  516. package/src/store/session/messages.ts +21 -0
  517. package/src/types/agent/base.ts +31 -1
  518. package/src/types/agent/task.ts +58 -2
  519. package/src/types/conversation/index.ts +7 -0
  520. package/src/types/ids/index.ts +41 -3
  521. package/src/types/invocation/__tests__/state.test.ts +37 -29
  522. package/src/types/invocation/index.ts +26 -10
  523. package/src/types/run/config.ts +12 -1
  524. package/src/types/run/events.ts +36 -1
  525. package/src/types/run/index.ts +8 -0
  526. package/src/types/run/metadata.ts +24 -1
  527. package/src/types/run/status.ts +33 -0
  528. package/src/types/session/ids.ts +34 -0
  529. package/src/types/session/index.ts +28 -0
  530. package/src/types/session/store.ts +229 -0
  531. package/src/utils/id.ts +55 -4
@@ -0,0 +1,92 @@
1
+ import type { SessionId } from '../../types/ids/index.js'
2
+ import type { SubSessionId, SummaryId, WorkspaceId } from '../../types/session/ids.js'
3
+ import type { ArchiveBackendRef } from '../retention/archive-backend-ref.js'
4
+ import type { DeliverableRef } from '../summary/deliverable.js'
5
+ import type { ActorRef } from './actor.js'
6
+
7
+ /**
8
+ * Full 11-variant status union. See session-hierarchy.md §4.4 and the merge
9
+ * state machine in §4.4.1. Absence of a `closed` state is load-bearing —
10
+ * completed sub-sessions land on `idle` and stay there for drill-down
11
+ * (Decision #5).
12
+ */
13
+ export type SubSessionStatus =
14
+ | 'pending'
15
+ | 'active'
16
+ | 'idle'
17
+ | 'failed'
18
+ | 'awaiting_merge'
19
+ | 'pending_merge'
20
+ | 'merging'
21
+ | 'merged'
22
+ | 'merge_conflict'
23
+ | 'merge_rejected'
24
+ | 'archived'
25
+
26
+ /**
27
+ * Discriminator for how a sub-session was created. Pattern doc §4.4
28
+ * enumerates four variants; the three kept here collapse `user_handoff`
29
+ * and `user_broadcast` into the single `user_handoff` kind (multi-recipient
30
+ * flows are encoded via `broadcastGroupId` in later phases).
31
+ */
32
+ export type SubSessionKind = 'agent_spawn' | 'user_handoff' | 'intervention'
33
+
34
+ /**
35
+ * Per-spawn failure policy for parallel fan-out. See session-hierarchy.md
36
+ * §4.4. Default is `delegate` — siblings continue and the parent agent
37
+ * decides what to do with partial results.
38
+ */
39
+ export type FailureMode = 'fail_fast' | 'delegate'
40
+
41
+ /**
42
+ * Completion contract the parent expects. See session-hierarchy.md §9.
43
+ *
44
+ * `summary_ref` is the default for agent delegation and interventions.
45
+ * `merge_back` is used by multi-user handoff; full spec lives in
46
+ * `collaboration-primitives.md`.
47
+ */
48
+ export type CompletionMode = 'summary_ref' | 'merge_back'
49
+
50
+ /**
51
+ * Re-export of the real {@link DeliverableRef} discriminated union. The
52
+ * concrete shape lives in `../summary/deliverable.ts` — see
53
+ * session-hierarchy.md §4.7 / §8.1. Phase 5 (this phase) replaced the Phase 1
54
+ * `unknown` placeholder with the real type.
55
+ */
56
+ export type { DeliverableRef }
57
+
58
+ /**
59
+ * Edge between a parent {@link Session} and a child session, carrying the
60
+ * delegation metadata. The child session itself lives in `SessionStore`
61
+ * like any other session — see session-hierarchy.md §4.4.
62
+ */
63
+ export interface SubSession {
64
+ id: SubSessionId
65
+ parentSessionId: SessionId
66
+ childSessionId: SessionId
67
+ kind: SubSessionKind
68
+ status: SubSessionStatus
69
+ spawnedBy: ActorRef
70
+ spawnedAt: Date
71
+ failureMode: FailureMode
72
+ completionMode: CompletionMode
73
+ workspaceId: WorkspaceId | null
74
+ /**
75
+ * For interventions, the immutable artifact being addressed. Chains form
76
+ * a strict acyclic DAG — see session-hierarchy.md §4.5.
77
+ */
78
+ prevArtifactRef?: DeliverableRef
79
+ /** Fan-out bookkeeping for broadcasts (§4.4). */
80
+ broadcastGroupId?: string
81
+ /** Populated by {@link SessionSummaryMaterializer} on terminalization (§8). */
82
+ summaryRef?: SummaryId
83
+ /**
84
+ * Pointer to the archive bundle for this sub-session. Present iff
85
+ * `status === 'archived'` (pattern doc §12.3). The paired
86
+ * {@link archivedAt} timestamp captures when the bundle was sealed.
87
+ * Cleared by {@link ArchivalManager.restore}.
88
+ */
89
+ archiveRef?: ArchiveBackendRef
90
+ archivedAt?: Date
91
+ updatedAt: Date
92
+ }
@@ -0,0 +1,13 @@
1
+ import type { TenantId } from '../../types/ids/index.js'
2
+
3
+ /**
4
+ * Tenancy boundary for everything in the hierarchy.
5
+ *
6
+ * Intentionally thin — naming, billing, SSO, and quotas live outside the SDK
7
+ * (session-hierarchy.md §4.1 Convention #17). No API surface crosses
8
+ * {@link TenantId}.
9
+ */
10
+ export interface Tenant {
11
+ id: TenantId
12
+ createdAt: Date
13
+ }
@@ -0,0 +1,15 @@
1
+ // Top-level barrel for the session hierarchy module.
2
+ // Phase 1 populates `hierarchy/`; Phase 2 adds `events/`; Phase 3 adds
3
+ // `workspace/` + `errors.ts`; Phase 4 adds `handoff/`; Phase 5 adds
4
+ // `summary/` + `intervention/`; Phase 7 adds `migration/`; Phase 8 adds
5
+ // `retention/`.
6
+
7
+ export * from './hierarchy/index.js'
8
+ export * from './events/index.js'
9
+ export * from './workspace/index.js'
10
+ export * from './handoff/index.js'
11
+ export * from './summary/index.js'
12
+ export * from './intervention/index.js'
13
+ export * from './migration/index.js'
14
+ export * from './retention/index.js'
15
+ export { TenantIsolationError, WorkspaceBackendError, AncestryCycleError } from './errors.js'
@@ -0,0 +1,234 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import type { SessionId } from '../../../types/ids/index.js'
3
+ import type { DeliverableId, SubSessionId, SummaryId } from '../../../types/session/ids.js'
4
+ import type { DeliverableRef, SessionSummaryDeliverable } from '../../summary/deliverable.js'
5
+ import {
6
+ ArtifactRefCycleError,
7
+ type InterventionChainLoader,
8
+ InterventionDepthExceeded,
9
+ type PrevArtifactNode,
10
+ validatePrevArtifactChain,
11
+ } from '../prev-artifact.js'
12
+
13
+ // Helpers -------------------------------------------------------------------
14
+
15
+ function sessionId(n: number): SessionId {
16
+ return `ses_${n}` as SessionId
17
+ }
18
+
19
+ function subId(n: number): SubSessionId {
20
+ return `sub_${n}` as SubSessionId
21
+ }
22
+
23
+ function summaryDeliverable(targetSession: SessionId): SessionSummaryDeliverable {
24
+ return {
25
+ id: 'del_test' as DeliverableId,
26
+ kind: 'session_summary',
27
+ sessionId: targetSession,
28
+ summaryRef: 'sum_test' as SummaryId,
29
+ at: new Date('2026-04-17T00:00:00Z'),
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Build a loader that walks a pre-configured chain. `chain[i]` is the node
35
+ * returned for the i'th step (keyed by the session id the previous step
36
+ * targeted). `nodesBySession` keys the loader by `sessionId`.
37
+ */
38
+ function buildLoader(
39
+ nodes: Array<PrevArtifactNode & { bySession: SessionId }>,
40
+ ): InterventionChainLoader {
41
+ const map = new Map<SessionId, PrevArtifactNode>()
42
+ for (const n of nodes) {
43
+ map.set(n.bySession, {
44
+ subSessionId: n.subSessionId,
45
+ sessionId: n.sessionId,
46
+ ...(n.prevArtifactRef !== undefined && { prevArtifactRef: n.prevArtifactRef }),
47
+ })
48
+ }
49
+ return {
50
+ loadAncestor: async (sid) => map.get(sid) ?? null,
51
+ }
52
+ }
53
+
54
+ describe('validatePrevArtifactChain', () => {
55
+ it('accepts a depth-1 chain (direct parent only)', async () => {
56
+ const loader = buildLoader([
57
+ {
58
+ bySession: sessionId(1),
59
+ subSessionId: subId(1),
60
+ sessionId: sessionId(1),
61
+ // No prevArtifactRef — chain terminates here.
62
+ },
63
+ ])
64
+ const chain = await validatePrevArtifactChain(
65
+ loader,
66
+ subId(100),
67
+ summaryDeliverable(sessionId(1)),
68
+ 10,
69
+ )
70
+ expect(chain).toEqual([subId(1)])
71
+ })
72
+
73
+ it('accepts a depth-2 chain', async () => {
74
+ const loader = buildLoader([
75
+ {
76
+ bySession: sessionId(1),
77
+ subSessionId: subId(1),
78
+ sessionId: sessionId(1),
79
+ prevArtifactRef: summaryDeliverable(sessionId(2)),
80
+ },
81
+ {
82
+ bySession: sessionId(2),
83
+ subSessionId: subId(2),
84
+ sessionId: sessionId(2),
85
+ },
86
+ ])
87
+ const chain = await validatePrevArtifactChain(
88
+ loader,
89
+ subId(100),
90
+ summaryDeliverable(sessionId(1)),
91
+ 10,
92
+ )
93
+ expect(chain).toEqual([subId(1), subId(2)])
94
+ })
95
+
96
+ it('accepts a chain exactly at the depth limit', async () => {
97
+ // 10-deep chain with maxDepth = 10.
98
+ const nodes: Array<PrevArtifactNode & { bySession: SessionId }> = []
99
+ for (let i = 1; i <= 10; i++) {
100
+ nodes.push({
101
+ bySession: sessionId(i),
102
+ subSessionId: subId(i),
103
+ sessionId: sessionId(i),
104
+ ...(i < 10 && { prevArtifactRef: summaryDeliverable(sessionId(i + 1)) }),
105
+ })
106
+ }
107
+ const loader = buildLoader(nodes)
108
+ const chain = await validatePrevArtifactChain(
109
+ loader,
110
+ subId(100),
111
+ summaryDeliverable(sessionId(1)),
112
+ 10,
113
+ )
114
+ expect(chain).toHaveLength(10)
115
+ })
116
+
117
+ it('rejects a chain that would exceed the depth limit', async () => {
118
+ // 11-deep chain with maxDepth = 10.
119
+ const nodes: Array<PrevArtifactNode & { bySession: SessionId }> = []
120
+ for (let i = 1; i <= 11; i++) {
121
+ nodes.push({
122
+ bySession: sessionId(i),
123
+ subSessionId: subId(i),
124
+ sessionId: sessionId(i),
125
+ ...(i < 11 && { prevArtifactRef: summaryDeliverable(sessionId(i + 1)) }),
126
+ })
127
+ }
128
+ const loader = buildLoader(nodes)
129
+ await expect(
130
+ validatePrevArtifactChain(loader, subId(100), summaryDeliverable(sessionId(1)), 10),
131
+ ).rejects.toBeInstanceOf(InterventionDepthExceeded)
132
+ })
133
+
134
+ it('rejects self-reference as a cycle', async () => {
135
+ // proposedChild's prev points at a node whose subSessionId == proposedChild.
136
+ const loader = buildLoader([
137
+ {
138
+ bySession: sessionId(1),
139
+ subSessionId: subId(100), // SAME id as proposedChild
140
+ sessionId: sessionId(1),
141
+ },
142
+ ])
143
+ await expect(
144
+ validatePrevArtifactChain(loader, subId(100), summaryDeliverable(sessionId(1)), 10),
145
+ ).rejects.toBeInstanceOf(ArtifactRefCycleError)
146
+ })
147
+
148
+ it('rejects a 2-cycle (A -> B -> A)', async () => {
149
+ const loader = buildLoader([
150
+ {
151
+ bySession: sessionId(1),
152
+ subSessionId: subId(1),
153
+ sessionId: sessionId(1),
154
+ prevArtifactRef: summaryDeliverable(sessionId(2)),
155
+ },
156
+ {
157
+ bySession: sessionId(2),
158
+ subSessionId: subId(2),
159
+ sessionId: sessionId(2),
160
+ prevArtifactRef: summaryDeliverable(sessionId(1)),
161
+ },
162
+ ])
163
+ await expect(
164
+ validatePrevArtifactChain(loader, subId(100), summaryDeliverable(sessionId(1)), 10),
165
+ ).rejects.toBeInstanceOf(ArtifactRefCycleError)
166
+ })
167
+
168
+ it('rejects a 3-cycle (A -> B -> C -> A)', async () => {
169
+ const loader = buildLoader([
170
+ {
171
+ bySession: sessionId(1),
172
+ subSessionId: subId(1),
173
+ sessionId: sessionId(1),
174
+ prevArtifactRef: summaryDeliverable(sessionId(2)),
175
+ },
176
+ {
177
+ bySession: sessionId(2),
178
+ subSessionId: subId(2),
179
+ sessionId: sessionId(2),
180
+ prevArtifactRef: summaryDeliverable(sessionId(3)),
181
+ },
182
+ {
183
+ bySession: sessionId(3),
184
+ subSessionId: subId(3),
185
+ sessionId: sessionId(3),
186
+ prevArtifactRef: summaryDeliverable(sessionId(1)),
187
+ },
188
+ ])
189
+ await expect(
190
+ validatePrevArtifactChain(loader, subId(100), summaryDeliverable(sessionId(1)), 10),
191
+ ).rejects.toBeInstanceOf(ArtifactRefCycleError)
192
+ })
193
+
194
+ it('returns an empty chain for a non-session_summary deliverable', async () => {
195
+ const fileRef: DeliverableRef = {
196
+ id: 'del_file' as DeliverableId,
197
+ kind: 'file',
198
+ path: 'a.txt',
199
+ contentHash: 'abc',
200
+ sizeBytes: 0,
201
+ }
202
+ const loader: InterventionChainLoader = {
203
+ loadAncestor: async () => null,
204
+ }
205
+ const chain = await validatePrevArtifactChain(loader, subId(100), fileRef, 10)
206
+ expect(chain).toEqual([])
207
+ })
208
+
209
+ it('terminates cleanly on unknown ancestor (archived/tombstoned)', async () => {
210
+ const loader = buildLoader([
211
+ // no matching node — loadAncestor returns null for any id
212
+ ])
213
+ const chain = await validatePrevArtifactChain(
214
+ loader,
215
+ subId(100),
216
+ summaryDeliverable(sessionId(42)),
217
+ 10,
218
+ )
219
+ expect(chain).toEqual([])
220
+ })
221
+
222
+ it('rejects zero/negative maxDepth as depth-exceeded up front', async () => {
223
+ const loader = buildLoader([
224
+ {
225
+ bySession: sessionId(1),
226
+ subSessionId: subId(1),
227
+ sessionId: sessionId(1),
228
+ },
229
+ ])
230
+ await expect(
231
+ validatePrevArtifactChain(loader, subId(100), summaryDeliverable(sessionId(1)), 0),
232
+ ).rejects.toBeInstanceOf(InterventionDepthExceeded)
233
+ })
234
+ })
@@ -0,0 +1,16 @@
1
+ // Sub-barrel for the intervention DAG module (Convention #4).
2
+ //
3
+ // See session-hierarchy.md §4.5 — intervention chains via `prevArtifactRef`
4
+ // form a strict acyclic DAG capped by
5
+ // `Project.config.maxInterventionDepth`. This module owns the pre-commit
6
+ // validator + typed errors; sub-session wiring is Phase 6.
7
+
8
+ export {
9
+ ArtifactRefCycleError,
10
+ InterventionDepthExceeded,
11
+ validatePrevArtifactChain,
12
+ } from './prev-artifact.js'
13
+ export type {
14
+ InterventionChainLoader,
15
+ PrevArtifactNode,
16
+ } from './prev-artifact.js'
@@ -0,0 +1,180 @@
1
+ /**
2
+ * prevArtifactRef DAG primitives — acyclic walker, cycle detection, depth
3
+ * enforcement. See session-hierarchy.md §4.5.
4
+ *
5
+ * Intervention chains link successive follow-up sub-sessions via
6
+ * `SubSession.prevArtifactRef`, forming a strict acyclic DAG over prior
7
+ * completed sessions. This module supplies the pre-commit validator that
8
+ * rejects any insertion that would close a cycle or overflow
9
+ * {@link Project.config.maxInterventionDepth} (default 10).
10
+ *
11
+ * Convention #5: deny-by-default. Cycle or depth violation rejects with a
12
+ * typed error; callers never get a silently-truncated chain.
13
+ *
14
+ * Convention #0: no silent fallbacks. The walker surfaces corruption as
15
+ * `ArtifactRefCycleError` rather than infinite-looping.
16
+ */
17
+
18
+ import type { SessionId } from '../../types/ids/index.js'
19
+ import type { SubSessionId } from '../../types/session/ids.js'
20
+ import type { DeliverableRef } from '../summary/deliverable.js'
21
+
22
+ /**
23
+ * Minimal record the validator needs to step ancestrally from one
24
+ * sub-session to its predecessor. Concrete stores provide this projection.
25
+ *
26
+ * `sessionId` is the completed session this node represents (the one the
27
+ * incoming {@link DeliverableRef} pointed at). `subSessionId` is its own
28
+ * sub-session edge id — used for the visited-set so intervention chains form
29
+ * an acyclic DAG over sub-session identities.
30
+ */
31
+ export interface PrevArtifactNode {
32
+ readonly subSessionId: SubSessionId
33
+ readonly sessionId: SessionId
34
+ readonly prevArtifactRef?: DeliverableRef
35
+ }
36
+
37
+ /**
38
+ * Raised when {@link validatePrevArtifactChain} detects a cycle — revisiting
39
+ * a sub-session id already in the ancestry set. Indicates a bug in the caller
40
+ * (or pre-existing store corruption); the write must be rejected.
41
+ */
42
+ export class ArtifactRefCycleError extends Error {
43
+ readonly details: {
44
+ readonly startSubSessionId: SubSessionId
45
+ readonly cyclePath: readonly SubSessionId[]
46
+ }
47
+
48
+ constructor(details: {
49
+ startSubSessionId: SubSessionId
50
+ cyclePath: readonly SubSessionId[]
51
+ }) {
52
+ super(
53
+ `prevArtifactRef cycle starting at ${details.startSubSessionId}: ${details.cyclePath.join(' -> ')}`,
54
+ )
55
+ this.name = 'ArtifactRefCycleError'
56
+ this.details = details
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Raised when the resolved chain length exceeds the configured intervention
62
+ * depth limit (`Project.config.maxInterventionDepth`). Convention #5
63
+ * deny-by-default — the kernel does not auto-truncate.
64
+ */
65
+ export class InterventionDepthExceeded extends Error {
66
+ readonly details: {
67
+ readonly subSessionId: SubSessionId
68
+ readonly depth: number
69
+ readonly limit: number
70
+ }
71
+
72
+ constructor(details: { subSessionId: SubSessionId; depth: number; limit: number }) {
73
+ super(
74
+ `Intervention chain depth ${details.depth} exceeds limit ${details.limit} at ${details.subSessionId}`,
75
+ )
76
+ this.name = 'InterventionDepthExceeded'
77
+ this.details = details
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Loader surface the validator queries to walk ancestry. Returning `null`
83
+ * means "no further ancestor" — the chain terminates cleanly. The loader is
84
+ * injected so tests can fake a chain without standing up a full
85
+ * {@link SessionStore}.
86
+ */
87
+ export interface InterventionChainLoader {
88
+ /**
89
+ * Resolves the ancestor node for the supplied {@link SessionId} — the
90
+ * session that the last step's `SessionSummaryDeliverable.sessionId` named.
91
+ * Returns `null` when no sub-session edge exists for that session (root
92
+ * session, or an archived/tombstoned ancestor — see §12.3).
93
+ */
94
+ loadAncestor(sessionId: SessionId): Promise<PrevArtifactNode | null>
95
+ }
96
+
97
+ /**
98
+ * Pre-commit validator for adding a `prevArtifactRef` on a proposed child
99
+ * sub-session. Walks from `candidateAncestor` backwards through
100
+ * `loader.loadAncestor`, seeding the visited-set with `proposedChild` so a
101
+ * cycle (the candidate chain loops back to the child) is rejected
102
+ * immediately.
103
+ *
104
+ * Returns the resolved ancestry chain (oldest last, length ≤ `maxDepth`),
105
+ * excluding `proposedChild` itself. The chain is ordered from
106
+ * immediate-ancestor to furthest-ancestor (reverse-chronological per §4.5).
107
+ *
108
+ * Throws:
109
+ * - {@link ArtifactRefCycleError} if the walk revisits `proposedChild` or
110
+ * any already-visited ancestor.
111
+ * - {@link InterventionDepthExceeded} if the chain would exceed `maxDepth`.
112
+ *
113
+ * Non-session_summary deliverables (file / message / artifact_blob) do not
114
+ * form chain links — the walker terminates cleanly when it encounters one,
115
+ * since only `kind: 'session_summary'` references another sub-session's
116
+ * ancestry.
117
+ */
118
+ export async function validatePrevArtifactChain(
119
+ loader: InterventionChainLoader,
120
+ proposedChild: SubSessionId,
121
+ candidateAncestor: DeliverableRef,
122
+ maxDepth: number,
123
+ ): Promise<readonly SubSessionId[]> {
124
+ if (maxDepth <= 0) {
125
+ throw new InterventionDepthExceeded({
126
+ subSessionId: proposedChild,
127
+ depth: 1,
128
+ limit: maxDepth,
129
+ })
130
+ }
131
+
132
+ // Non-session_summary refs are leaves — no chain links.
133
+ if (candidateAncestor.kind !== 'session_summary') {
134
+ return []
135
+ }
136
+
137
+ const visited = new Set<SubSessionId>([proposedChild])
138
+ const chain: SubSessionId[] = []
139
+
140
+ let currentRef: DeliverableRef | undefined = candidateAncestor
141
+
142
+ while (currentRef !== undefined) {
143
+ if (currentRef.kind !== 'session_summary') {
144
+ // Chain terminates on non-session deliverable.
145
+ return chain
146
+ }
147
+
148
+ // `SessionSummaryDeliverable.sessionId` names the completed session the
149
+ // ref points at. The loader resolves that to the sub-session edge
150
+ // carrying its own `prevArtifactRef` (if any), giving us the next step.
151
+ const ancestorNode = await loader.loadAncestor(currentRef.sessionId)
152
+ if (!ancestorNode) {
153
+ // Unknown ancestor (root session, or archived / tombstoned). Chain
154
+ // ends cleanly — absence is not a cycle.
155
+ return chain
156
+ }
157
+
158
+ if (visited.has(ancestorNode.subSessionId)) {
159
+ throw new ArtifactRefCycleError({
160
+ startSubSessionId: proposedChild,
161
+ cyclePath: [...chain, ancestorNode.subSessionId],
162
+ })
163
+ }
164
+
165
+ visited.add(ancestorNode.subSessionId)
166
+ chain.push(ancestorNode.subSessionId)
167
+
168
+ if (chain.length > maxDepth) {
169
+ throw new InterventionDepthExceeded({
170
+ subSessionId: proposedChild,
171
+ depth: chain.length,
172
+ limit: maxDepth,
173
+ })
174
+ }
175
+
176
+ currentRef = ancestorNode.prevArtifactRef
177
+ }
178
+
179
+ return chain
180
+ }