@north-light/crouter 0.3.312 → 0.3.313

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 (495) hide show
  1. package/dist/api/client.d.ts +27 -30
  2. package/dist/api/client.js +80 -67
  3. package/dist/api/dto/broker-ops.d.ts +10 -20
  4. package/dist/api/dto/canvas.d.ts +1 -10
  5. package/dist/api/dto/health.d.ts +113 -0
  6. package/dist/api/dto/human-requests.d.ts +14 -3
  7. package/dist/api/dto/human.d.ts +2 -48
  8. package/dist/api/dto/human.js +3 -2
  9. package/dist/api/dto/inbox.d.ts +14 -0
  10. package/dist/api/dto/mail.d.ts +43 -0
  11. package/dist/api/dto/nodes.d.ts +11 -8
  12. package/dist/api/dto/recovery.d.ts +96 -0
  13. package/dist/api/dto/reviews.d.ts +2 -2
  14. package/dist/api/routes.d.ts +9 -6
  15. package/dist/api/routes.js +11 -11
  16. package/dist/build-root.d.ts +4 -0
  17. package/dist/build-root.js +11 -1
  18. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
  19. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
  20. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
  22. package/dist/cli.js +10 -1
  23. package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
  24. package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
  25. package/dist/clients/attach/chrome/canvas-panels.js +1 -1
  26. package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
  27. package/dist/clients/attach/chrome/inbox-strip.js +17 -9
  28. package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
  29. package/dist/clients/attach/chrome/ticket-panel.js +77 -46
  30. package/dist/clients/attach/overlays/graph.js +6 -9
  31. package/dist/clients/attach/render/chat-view.d.ts +5 -4
  32. package/dist/clients/attach/render/chat-view.js +22 -13
  33. package/dist/clients/attach/render/page-block.d.ts +11 -7
  34. package/dist/clients/attach/render/page-block.js +64 -55
  35. package/dist/clients/attach/viewer.js +746 -735
  36. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
  37. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
  38. package/dist/clients/inbox/controller.d.ts +42 -14
  39. package/dist/clients/inbox/controller.js +240 -124
  40. package/dist/clients/inbox/dto-adapt.d.ts +28 -0
  41. package/dist/clients/inbox/dto-adapt.js +93 -0
  42. package/dist/clients/inbox/page-adapter.d.ts +5 -4
  43. package/dist/clients/inbox/page-adapter.js +12 -12
  44. package/dist/clients/inbox/resolve.d.ts +10 -5
  45. package/dist/clients/inbox/resolve.js +13 -12
  46. package/dist/clients/inbox/review/review-client.d.ts +0 -1
  47. package/dist/clients/inbox/review/review-client.js +0 -4
  48. package/dist/clients/inbox/review-adapter.d.ts +2 -1
  49. package/dist/clients/inbox/review-adapter.js +3 -5
  50. package/dist/clients/inbox/surface.d.ts +2 -2
  51. package/dist/clients/inbox/surface.js +19 -8
  52. package/dist/clients/inbox/tui.d.ts +3 -3
  53. package/dist/commands/__tests__/human.test.js +31 -15
  54. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
  55. package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
  56. package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
  57. package/dist/commands/api-client.d.ts +5 -4
  58. package/dist/commands/api-client.js +13 -7
  59. package/dist/commands/canvas-history/shared.js +1 -1
  60. package/dist/commands/canvas-history.js +1 -1
  61. package/dist/commands/canvas-roster.js +1 -1
  62. package/dist/commands/canvas.js +1 -2
  63. package/dist/commands/human/feedback.js +20 -17
  64. package/dist/commands/human/prompts.js +45 -36
  65. package/dist/commands/human/queue.js +73 -123
  66. package/dist/commands/human/review.js +6 -16
  67. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
  68. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
  69. package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
  70. package/dist/commands/node-inspect-artifacts.js +1 -1
  71. package/dist/commands/node-lifecycle-revive.d.ts +2 -2
  72. package/dist/commands/node-lifecycle-revive.js +9 -19
  73. package/dist/commands/pkg/plugin-manage.js +0 -1
  74. package/dist/commands/profile/show.js +4 -12
  75. package/dist/commands/surface-tmux-spread.js +1 -5
  76. package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
  77. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
  78. package/dist/commands/sys/branch.d.ts +2 -0
  79. package/dist/commands/sys/branch.js +19 -0
  80. package/dist/commands/sys/config.js +106 -33
  81. package/dist/commands/sys/daemon.d.ts +2 -0
  82. package/dist/commands/sys/daemon.js +130 -7
  83. package/dist/commands/sys/doctor.js +5 -15
  84. package/dist/commands/sys/migrate.js +21 -92
  85. package/dist/commands/sys/setup-settings-runner.js +4 -2
  86. package/dist/commands/sys.js +2 -15
  87. package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
  88. package/dist/core/__tests__/boot.test.js +32 -25
  89. package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
  90. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
  91. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
  92. package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
  93. package/dist/core/__tests__/canvas.test.js +18 -47
  94. package/dist/core/__tests__/child-death-wake.test.js +29 -7
  95. package/dist/core/__tests__/cli-help-contract.test.js +2 -0
  96. package/dist/core/__tests__/close.test.js +29 -10
  97. package/dist/core/__tests__/collectible.test.js +2 -1
  98. package/dist/core/__tests__/config-change-delta.test.js +2 -0
  99. package/dist/core/__tests__/context-intro.test.js +13 -1
  100. package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
  101. package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
  102. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
  103. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
  104. package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
  105. package/dist/core/__tests__/daemon-boot.test.js +51 -14
  106. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  107. package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
  108. package/dist/core/__tests__/focuses.test.js +10 -5
  109. package/dist/core/__tests__/helpers/harness.js +50 -18
  110. package/dist/core/__tests__/history-inbox.test.js +12 -16
  111. package/dist/core/__tests__/human-action-delivery.test.js +48 -28
  112. package/dist/core/__tests__/human-actions.test.js +7 -3
  113. package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
  114. package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
  115. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
  116. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
  117. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
  118. package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
  119. package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
  120. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
  121. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +16 -3
  122. package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
  123. package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
  124. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
  125. package/dist/core/__tests__/integration/revive.test.js +67 -21
  126. package/dist/core/__tests__/integration/spawn-root.test.js +51 -8
  127. package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
  128. package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
  129. package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
  130. package/dist/core/__tests__/kickoff.test.js +36 -39
  131. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
  132. package/dist/core/__tests__/lifecycle.test.js +2 -1
  133. package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
  134. package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
  135. package/dist/core/__tests__/migration.test.js +145 -31
  136. package/dist/core/__tests__/model-pin-durability.test.js +4 -1
  137. package/dist/core/__tests__/model-routes-config.test.js +13 -5
  138. package/dist/core/__tests__/node-outcome.test.js +93 -26
  139. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
  140. package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
  141. package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
  142. package/dist/core/__tests__/passive-subscription.test.js +50 -157
  143. package/dist/core/__tests__/plugin-kinds.test.js +6 -4
  144. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
  145. package/dist/core/__tests__/plugin-page-components.test.js +6 -4
  146. package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
  147. package/dist/core/__tests__/profile-project-memory-delivery.test.js +4 -1
  148. package/dist/core/__tests__/prune.test.js +11 -5
  149. package/dist/core/__tests__/push-final-guard.test.js +14 -7
  150. package/dist/core/__tests__/relaunch-root.test.js +30 -2
  151. package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
  152. package/dist/core/__tests__/repository-root-identity.test.js +4 -0
  153. package/dist/core/__tests__/review-model-floor.test.js +6 -3
  154. package/dist/core/__tests__/revive-all.test.js +13 -3
  155. package/dist/core/__tests__/revive-capacity.test.js +26 -4
  156. package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
  157. package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
  158. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
  159. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
  160. package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
  161. package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
  162. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
  163. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
  164. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
  165. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +2 -1
  166. package/dist/core/__tests__/stop-guard.test.js +2 -1
  167. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
  168. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +18 -4
  169. package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
  170. package/dist/core/bootstrap.js +2 -0
  171. package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
  172. package/dist/core/broker-client/transport-socket.d.ts +1 -0
  173. package/dist/core/broker-client/transport-socket.js +13 -5
  174. package/dist/core/canvas/__tests__/attention.test.js +29 -35
  175. package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
  176. package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
  177. package/dist/core/canvas/attention.d.ts +2 -5
  178. package/dist/core/canvas/attention.js +15 -64
  179. package/dist/core/canvas/boot.d.ts +6 -7
  180. package/dist/core/canvas/boot.js +5 -9
  181. package/dist/core/canvas/canvas.d.ts +13 -109
  182. package/dist/core/canvas/canvas.js +140 -401
  183. package/dist/core/canvas/crons.d.ts +2 -0
  184. package/dist/core/canvas/crons.js +16 -15
  185. package/dist/core/canvas/daemon-owner.js +10 -0
  186. package/dist/core/canvas/db.d.ts +2 -2
  187. package/dist/core/canvas/db.js +2 -18
  188. package/dist/core/canvas/deliveries.d.ts +104 -0
  189. package/dist/core/canvas/deliveries.js +354 -0
  190. package/dist/core/canvas/executions.d.ts +29 -0
  191. package/dist/core/canvas/executions.js +68 -0
  192. package/dist/core/canvas/history.js +35 -35
  193. package/dist/core/canvas/index.d.ts +3 -1
  194. package/dist/core/canvas/index.js +3 -1
  195. package/dist/core/canvas/migrations.js +20 -12
  196. package/dist/core/canvas/nav-model.js +1 -3
  197. package/dist/core/canvas/nav-render.d.ts +4 -4
  198. package/dist/core/canvas/nav-render.js +11 -21
  199. package/dist/core/canvas/node-sql-migration.d.ts +3 -0
  200. package/dist/core/canvas/node-sql-migration.js +261 -0
  201. package/dist/core/canvas/paths.d.ts +2 -16
  202. package/dist/core/canvas/paths.js +2 -31
  203. package/dist/core/canvas/recovery.d.ts +76 -0
  204. package/dist/core/canvas/recovery.js +588 -0
  205. package/dist/core/canvas/remote-canvas-source.js +4 -0
  206. package/dist/core/canvas/render-source.d.ts +16 -27
  207. package/dist/core/canvas/render-source.js +16 -45
  208. package/dist/core/canvas/sessions.d.ts +33 -0
  209. package/dist/core/canvas/sessions.js +78 -0
  210. package/dist/core/canvas/types.d.ts +33 -33
  211. package/dist/core/canvas/types.js +2 -5
  212. package/dist/core/canvas/waits.d.ts +18 -0
  213. package/dist/core/canvas/waits.js +70 -0
  214. package/dist/core/canvas/worktrees.d.ts +40 -0
  215. package/dist/core/canvas/worktrees.js +93 -0
  216. package/dist/core/config.d.ts +17 -12
  217. package/dist/core/config.js +106 -155
  218. package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
  219. package/dist/core/feed/feed.d.ts +0 -6
  220. package/dist/core/feed/feed.js +68 -56
  221. package/dist/core/feed/inbox.d.ts +7 -81
  222. package/dist/core/feed/inbox.js +46 -378
  223. package/dist/core/feed/messages.d.ts +58 -0
  224. package/dist/core/feed/messages.js +217 -0
  225. package/dist/core/fs-utils.d.ts +4 -0
  226. package/dist/core/fs-utils.js +21 -1
  227. package/dist/core/human/answer.d.ts +1 -1
  228. package/dist/core/human/answer.js +1 -1
  229. package/dist/core/human/claim.d.ts +1 -1
  230. package/dist/core/human/claim.js +2 -4
  231. package/dist/core/human/component-docs.js +1 -1
  232. package/dist/core/human/feedback-companion.js +3 -2
  233. package/dist/core/human/feedback.d.ts +5 -8
  234. package/dist/core/human/feedback.js +57 -85
  235. package/dist/core/human/page-authoring.d.ts +30 -0
  236. package/dist/core/human/page-authoring.js +19 -0
  237. package/dist/core/human/requests.d.ts +136 -0
  238. package/dist/core/human/requests.js +515 -0
  239. package/dist/core/human/root.d.ts +0 -7
  240. package/dist/core/human/root.js +0 -17
  241. package/dist/core/human/scan.d.ts +2 -7
  242. package/dist/core/human/scan.js +48 -132
  243. package/dist/core/human/summary.d.ts +1 -1
  244. package/dist/core/human/summary.js +1 -1
  245. package/dist/core/human/tickets.d.ts +23 -83
  246. package/dist/core/human/tickets.js +92 -243
  247. package/dist/core/human/types.d.ts +5 -1
  248. package/dist/core/installed-plugins.js +8 -3
  249. package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
  250. package/dist/core/locked-file.d.ts +6 -3
  251. package/dist/core/locked-file.js +36 -9
  252. package/dist/core/memory/extensions.js +2 -0
  253. package/dist/core/preview-registry.js +0 -1
  254. package/dist/core/profiles/__tests__/env-store.test.js +2 -0
  255. package/dist/core/profiles/default-binding.d.ts +0 -4
  256. package/dist/core/profiles/default-binding.js +12 -58
  257. package/dist/core/profiles/env-store.js +8 -3
  258. package/dist/core/profiles/manifest.d.ts +2 -37
  259. package/dist/core/profiles/manifest.js +35 -161
  260. package/dist/core/profiles/select.js +3 -0
  261. package/dist/core/review/__tests__/capture-origin.test.js +13 -2
  262. package/dist/core/review/__tests__/comments.test.js +28 -10
  263. package/dist/core/review/__tests__/remap.test.js +28 -10
  264. package/dist/core/review/__tests__/stage-identity.test.js +17 -7
  265. package/dist/core/review/birth.d.ts +1 -1
  266. package/dist/core/review/birth.js +34 -5
  267. package/dist/core/review/comments.js +1 -1
  268. package/dist/core/review/document.js +1 -1
  269. package/dist/core/review/project.d.ts +5 -1
  270. package/dist/core/review/project.js +14 -36
  271. package/dist/core/review/realize.d.ts +3 -6
  272. package/dist/core/review/realize.js +51 -168
  273. package/dist/core/review/remap.js +1 -1
  274. package/dist/core/review/stage.d.ts +3 -2
  275. package/dist/core/review/stage.js +2 -3
  276. package/dist/core/review/store.d.ts +3 -21
  277. package/dist/core/review/store.js +140 -186
  278. package/dist/core/review/types.d.ts +0 -1
  279. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
  280. package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
  281. package/dist/core/runtime/broker/auth-reload.js +9 -10
  282. package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
  283. package/dist/core/runtime/broker/daemon-ops.js +42 -9
  284. package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
  285. package/dist/core/runtime/broker/extension-abort.js +11 -0
  286. package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
  287. package/dist/core/runtime/broker/fault-retry.js +142 -95
  288. package/dist/core/runtime/broker/inbox.d.ts +4 -32
  289. package/dist/core/runtime/broker/inbox.js +4 -92
  290. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  291. package/dist/core/runtime/broker/rebind.js +21 -12
  292. package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
  293. package/dist/core/runtime/broker-persona-guidance.js +2 -13
  294. package/dist/core/runtime/broker.js +28 -22
  295. package/dist/core/runtime/close.d.ts +3 -9
  296. package/dist/core/runtime/close.js +16 -27
  297. package/dist/core/runtime/fault.d.ts +3 -93
  298. package/dist/core/runtime/fault.js +9 -419
  299. package/dist/core/runtime/kickoff.d.ts +3 -6
  300. package/dist/core/runtime/kickoff.js +12 -18
  301. package/dist/core/runtime/launch.js +1 -1
  302. package/dist/core/runtime/lifecycle.js +40 -7
  303. package/dist/core/runtime/placement.js +2 -2
  304. package/dist/core/runtime/recycle.js +8 -2
  305. package/dist/core/runtime/reset.js +22 -6
  306. package/dist/core/runtime/revive.js +226 -218
  307. package/dist/core/runtime/spawn.js +14 -3
  308. package/dist/core/scoped-state/db.d.ts +7 -0
  309. package/dist/core/scoped-state/db.js +92 -0
  310. package/dist/core/scoped-state/migrate.d.ts +11 -0
  311. package/dist/core/scoped-state/migrate.js +198 -0
  312. package/dist/core/scoped-state/paths.d.ts +9 -0
  313. package/dist/core/scoped-state/paths.js +27 -0
  314. package/dist/core/scoped-state/profiles.d.ts +12 -0
  315. package/dist/core/scoped-state/profiles.js +62 -0
  316. package/dist/core/scoped-state/providers.d.ts +16 -0
  317. package/dist/core/scoped-state/providers.js +8 -0
  318. package/dist/core/scoped-state/schema.d.ts +3 -0
  319. package/dist/core/scoped-state/schema.js +26 -0
  320. package/dist/core/scoped-state/settings.d.ts +28 -0
  321. package/dist/core/scoped-state/settings.js +82 -0
  322. package/dist/core/subscription-state.d.ts +29 -48
  323. package/dist/core/subscription-state.js +176 -712
  324. package/dist/core/worktree-close.js +4 -4
  325. package/dist/core/worktree-mutation-async.js +2 -2
  326. package/dist/core/worktree-sweep.js +11 -16
  327. package/dist/core/worktree.js +6 -12
  328. package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
  329. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
  330. package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
  331. package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
  332. package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
  333. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +39 -15
  334. package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
  335. package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
  336. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
  337. package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
  338. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
  339. package/dist/daemon/api/__tests__/model-config.test.js +8 -8
  340. package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
  341. package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
  342. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
  343. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +4 -1
  344. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
  345. package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
  346. package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
  347. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
  348. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
  349. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +27 -41
  350. package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
  351. package/dist/daemon/api/bridge.js +1 -1
  352. package/dist/daemon/api/handlers/bash-jobs.js +6 -7
  353. package/dist/daemon/api/handlers/broker-ops.js +47 -84
  354. package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
  355. package/dist/daemon/api/handlers/broker-recovery.js +251 -0
  356. package/dist/daemon/api/handlers/canvas.js +2 -44
  357. package/dist/daemon/api/handlers/daemon.js +41 -0
  358. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  359. package/dist/daemon/api/handlers/health.js +10 -5
  360. package/dist/daemon/api/handlers/human-requests.js +168 -188
  361. package/dist/daemon/api/handlers/human.js +3 -151
  362. package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
  363. package/dist/daemon/api/handlers/inbox-page.js +89 -0
  364. package/dist/daemon/api/handlers/inbox.js +21 -120
  365. package/dist/daemon/api/handlers/messages.d.ts +1 -0
  366. package/dist/daemon/api/handlers/messages.js +73 -15
  367. package/dist/daemon/api/handlers/node-outcomes.js +58 -13
  368. package/dist/daemon/api/handlers/nodes.js +7 -13
  369. package/dist/daemon/api/handlers/reviews.js +4 -29
  370. package/dist/daemon/api/map.d.ts +25 -3
  371. package/dist/daemon/api/map.js +84 -14
  372. package/dist/daemon/api/server.js +68 -9
  373. package/dist/daemon/control.d.ts +18 -0
  374. package/dist/daemon/cron/disposition.d.ts +2 -0
  375. package/dist/daemon/cron/disposition.js +8 -5
  376. package/dist/daemon/cron/settle.js +37 -13
  377. package/dist/daemon/cron/sinks.d.ts +18 -1
  378. package/dist/daemon/cron/sinks.js +47 -93
  379. package/dist/daemon/crtrd-cli.js +4 -19
  380. package/dist/daemon/crtrd.d.ts +2 -0
  381. package/dist/daemon/crtrd.js +206 -81
  382. package/dist/daemon/fleet.js +5 -6
  383. package/dist/daemon/human/finish.d.ts +12 -24
  384. package/dist/daemon/human/finish.js +88 -285
  385. package/dist/daemon/human/settle.d.ts +40 -0
  386. package/dist/daemon/human/settle.js +89 -0
  387. package/dist/daemon/human/sweep.d.ts +20 -5
  388. package/dist/daemon/human/sweep.js +56 -60
  389. package/dist/daemon/manage.d.ts +21 -16
  390. package/dist/daemon/manage.js +85 -51
  391. package/dist/daemon/messaging/node-message.d.ts +1 -1
  392. package/dist/daemon/messaging/node-message.js +9 -12
  393. package/dist/daemon/park-activity.js +3 -3
  394. package/dist/daemon/reconcilers/bash-deadline.js +6 -7
  395. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  396. package/dist/daemon/reconcilers/broker-supervision.js +41 -19
  397. package/dist/daemon/reconcilers/controller-death.js +6 -18
  398. package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
  399. package/dist/daemon/reconcilers/delivery-lane.js +130 -0
  400. package/dist/daemon/reconcilers/live-obligation.js +3 -3
  401. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  402. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
  403. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
  404. package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
  405. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  406. package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
  407. package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
  408. package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
  409. package/dist/daemon/review/companion.js +5 -11
  410. package/dist/daemon/review/deliver.d.ts +1 -5
  411. package/dist/daemon/review/deliver.js +3 -52
  412. package/dist/daemon/review/finish.d.ts +2 -27
  413. package/dist/daemon/review/finish.js +79 -263
  414. package/dist/daemon/review/sweep.d.ts +3 -10
  415. package/dist/daemon/review/sweep.js +13 -131
  416. package/dist/daemon/startup-policy.d.ts +0 -5
  417. package/dist/daemon/startup-policy.js +0 -5
  418. package/dist/index.d.ts +2 -1
  419. package/dist/index.js +1 -1
  420. package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
  421. package/dist/migrations/__tests__/activation.test.js +9 -6
  422. package/dist/migrations/activation.d.ts +3 -2
  423. package/dist/migrations/activation.js +2 -4
  424. package/dist/migrations/corpus.d.ts +2 -5
  425. package/dist/migrations/corpus.js +9 -20
  426. package/dist/migrations/runner.d.ts +3 -1
  427. package/dist/migrations/runner.js +6 -2
  428. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
  429. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
  430. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
  431. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
  432. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
  433. package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
  434. package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
  435. package/dist/pi-extensions/canvas-passive-context.js +85 -37
  436. package/dist/pi-extensions/canvas-stophook.js +47 -31
  437. package/dist/shared/env.d.ts +1 -0
  438. package/dist/shared/env.js +3 -0
  439. package/package.json +1 -1
  440. package/runtime.lock.json +5 -5
  441. package/dist/clients/attach/__tests__/page-block.test.js +0 -54
  442. package/dist/clients/inbox/review-visibility.d.ts +0 -5
  443. package/dist/clients/inbox/review-visibility.js +0 -19
  444. package/dist/commands/canvas-rebuild-index.d.ts +0 -2
  445. package/dist/commands/canvas-rebuild-index.js +0 -46
  446. package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
  447. package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
  448. package/dist/core/__tests__/human-deliver.test.js +0 -256
  449. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
  450. package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
  451. package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
  452. package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
  453. package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
  454. package/dist/core/__tests__/phase4-review-store.test.js +0 -144
  455. package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
  456. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
  457. package/dist/core/canvas/human-deliveries.d.ts +0 -39
  458. package/dist/core/canvas/human-deliveries.js +0 -75
  459. package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
  460. package/dist/core/canvas/node-outcome-deliveries.js +0 -159
  461. package/dist/core/feed/passive.d.ts +0 -3
  462. package/dist/core/feed/passive.js +0 -53
  463. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
  464. package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
  465. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
  466. package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
  467. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
  468. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
  469. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
  470. package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
  471. package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
  472. package/dist/core/human/__tests__/page-tickets.test.js +0 -161
  473. package/dist/core/review/ticket-filter.d.ts +0 -17
  474. package/dist/core/review/ticket-filter.js +0 -21
  475. package/dist/core/runtime/broker/passive.d.ts +0 -17
  476. package/dist/core/runtime/broker/passive.js +0 -44
  477. package/dist/core/runtime/busy.d.ts +0 -46
  478. package/dist/core/runtime/busy.js +0 -150
  479. package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
  480. package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
  481. package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
  482. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
  483. package/dist/daemon/human/deliver-action.d.ts +0 -3
  484. package/dist/daemon/human/deliver-action.js +0 -9
  485. package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
  486. package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
  487. package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
  488. package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
  489. package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
  490. package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
  491. package/dist/daemon/startup-block-marker.d.ts +0 -25
  492. package/dist/daemon/startup-block-marker.js +0 -99
  493. /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
  494. /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
  495. /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
@@ -15,7 +15,8 @@ import { tmpdir } from 'node:os';
15
15
  import { join } from 'node:path';
16
16
  import * as tar from 'tar';
17
17
  import { resetScopeCache } from '../scope.js';
18
- import { resolvePageComponents } from '../config.js';
18
+ import { resolvePageComponents, updateRawConfigAtomically, writeRawConfig } from '../config.js';
19
+ import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
19
20
  import { validatePluginBundle } from '../command-plugins/bundle.js';
20
21
  let isolatedHome;
21
22
  let isolatedCwd;
@@ -30,6 +31,7 @@ beforeEach(() => {
30
31
  isolatedCwd = realpathSync(mkdtempSync(join(tmpdir(), 'crtr-page-components-cwd-')));
31
32
  process.env.HOME = isolatedHome;
32
33
  process.chdir(isolatedCwd);
34
+ initializeFreshScopedStore({ kind: 'user', root: join(isolatedHome, '.crouter') });
33
35
  resetScopeCache();
34
36
  });
35
37
  afterEach(() => {
@@ -60,7 +62,7 @@ test('an enabled user-scope plugin contributes its page components; a disabled o
60
62
  { kind: 'applet-card', display: true },
61
63
  ]);
62
64
  plantPlugin(root, 'zzz-disabled', ['ghost']);
63
- writeFileSync(join(root, 'config.json'), JSON.stringify({ plugins: { 'zzz-disabled': { enabled: false } } }));
65
+ writeRawConfig('user', { plugins: { 'zzz-disabled': { enabled: false } } });
64
66
  const components = resolvePageComponents();
65
67
  assert.deepEqual(components, [
66
68
  { kind: 'connector', description: 'Connector decision', useWhen: 'Use for a connector decision.', doc: 'Product contract.' },
@@ -70,9 +72,9 @@ test('an enabled user-scope plugin contributes its page components; a disabled o
70
72
  test('user config entries and plugin contributions resolve together, and a colliding kind is rejected', () => {
71
73
  const root = userRoot();
72
74
  plantPlugin(root, 'northlight', ['connector']);
73
- writeFileSync(join(root, 'config.json'), JSON.stringify({ page_components: ['approval'] }));
75
+ updateRawConfigAtomically('user', () => ({ page_components: ['approval'] }));
74
76
  assert.deepEqual(resolvePageComponents().map((component) => component.kind), ['approval', 'connector']);
75
- writeFileSync(join(root, 'config.json'), JSON.stringify({ page_components: ['connector'] }));
77
+ updateRawConfigAtomically('user', () => ({ page_components: ['connector'] }));
76
78
  assert.throws(() => resolvePageComponents(), /page component kind "connector" is registered by both config.json and plugin "northlight"/);
77
79
  });
78
80
  test('two plugins whose kinds derive one JSX tag are rejected, naming both sources', () => {
@@ -16,6 +16,7 @@ import { tmpdir } from 'node:os';
16
16
  import { join } from 'node:path';
17
17
  import { buildRoot } from '../../build-root.js';
18
18
  import { SUPPRESS_OUTPUT_LEAVES, LEAF_ICON_CP, SUMMARIZERS } from '../preview-registry.js';
19
+ import { ensureScopeInitialized } from '../config.js';
19
20
  import { resetScopeCache } from '../scope.js';
20
21
  // buildRoot() composes external command-plugin branches from the effective
21
22
  // enabled plugins (user scope + project ancestors). Pin HOME + profile to an
@@ -31,6 +32,7 @@ before(() => {
31
32
  process.env['HOME'] = home;
32
33
  delete process.env['CRTR_PROFILE_ID'];
33
34
  resetScopeCache();
35
+ ensureScopeInitialized('user', join(home, '.crouter'));
34
36
  });
35
37
  after(() => {
36
38
  if (realHome !== undefined)
@@ -18,9 +18,10 @@ import assert from 'node:assert/strict';
18
18
  import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
19
19
  import { tmpdir } from 'node:os';
20
20
  import { dirname, join } from 'node:path';
21
- import { closeDb } from '../canvas/db.js';
21
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
22
22
  import { resetScopeCache } from '../scope.js';
23
23
  import { createProfile } from '../profiles/manifest.js';
24
+ import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
24
25
  import { spawnNode } from '../runtime/nodes.js';
25
26
  import { memoryDir } from '../runtime/memory.js';
26
27
  import { clearSessionCache } from '../substrate/session-cache.js';
@@ -115,6 +116,8 @@ before(() => {
115
116
  canvasHome = realpathSync(mkdtempSync(join(tmpdir(), 'crtr-ppm-canvas-')));
116
117
  process.env['HOME'] = home;
117
118
  process.env['CRTR_HOME'] = canvasHome;
119
+ initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
120
+ migrate(openDb());
118
121
  // A project store answers only under the namespace its root INDEX.md
119
122
  // declares; without that declaration the store does not mount at all.
120
123
  const store = (slug, namespace) => {
@@ -3,8 +3,9 @@ import assert from 'node:assert/strict';
3
3
  import { mkdtempSync, rmSync, existsSync } from 'node:fs';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { join } from 'node:path';
6
- import { createNode, getRow, subscribe, recordPid, recordSpawn, subscribersOf, subscriptionsOf, pruneNodes, pruneToLimit, transitionStatusIntent, } from '../canvas/canvas.js';
7
- import { closeDb, openDb } from '../canvas/db.js';
6
+ import { createNode, getRow, subscribe, recordSpawn, subscribersOf, subscriptionsOf, pruneNodes, pruneToLimit, transitionStatusIntent, } from '../canvas/canvas.js';
7
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
8
+ import { beginExecution, recordExecutionPid } from '../canvas/executions.js';
8
9
  import { nodeDir } from '../canvas/paths.js';
9
10
  let home;
10
11
  const DAY = 86_400_000;
@@ -33,6 +34,10 @@ function totalEdges() {
33
34
  function markCollectibleTerminal(nodeId) {
34
35
  transitionStatusIntent(nodeId, { terminal_reason: 'closed' });
35
36
  }
37
+ function recordExecution(nodeId, pid) {
38
+ const executionId = beginExecution(nodeId, { daemonEpoch: 'test' });
39
+ recordExecutionPid(executionId, nodeId, pid);
40
+ }
36
41
  /** The standard fixture: three prunable terminal nodes (old), three survivors
37
42
  * (two old-but-live, one recent-but-dead), and edges that touch a pruned node
38
43
  * so cascade is observable. */
@@ -55,6 +60,7 @@ before(() => {
55
60
  beforeEach(() => {
56
61
  closeDb();
57
62
  rmSync(home, { recursive: true, force: true });
63
+ migrate(openDb());
58
64
  });
59
65
  after(() => {
60
66
  closeDb();
@@ -146,7 +152,7 @@ test('count pruning keeps all live nodes even when liveCount exceeds the cap', (
146
152
  // fall beyond rank 5 and are pruned.
147
153
  for (let i = 0; i < 5; i++) {
148
154
  createNode(node(`live-${i}`, { status: 'active', created: at(i) }));
149
- recordPid(`live-${i}`, process.pid); // process.pid is alive → isPidAlive true
155
+ recordExecution(`live-${i}`, process.pid); // process.pid is alive → isPidAlive true
150
156
  }
151
157
  createNode(node('old-a', { status: 'dead', created: at(100) }));
152
158
  createNode(node('old-b', { status: 'done', created: at(101) }));
@@ -164,7 +170,7 @@ test('count pruning deletes the oldest terminal nodes beyond max(cap, liveCount)
164
170
  // Ranked by recency DESC: live-0, term-0, term-1 (top 3, kept), then
165
171
  // term-2, term-3, term-4 (rank >= 3, pruned).
166
172
  createNode(node('live-0', { status: 'idle', created: at(0) }));
167
- recordPid('live-0', process.pid);
173
+ recordExecution('live-0', process.pid);
168
174
  for (let i = 0; i < 5; i++) {
169
175
  const id = `term-${i}`;
170
176
  createNode(node(id, { status: 'dead', created: at(10 + i) }));
@@ -185,7 +191,7 @@ test('count pruning deletes the oldest terminal nodes beyond max(cap, liveCount)
185
191
  });
186
192
  test('count pruning dry-run reports candidates without deleting rows or dirs', () => {
187
193
  createNode(node('live-0', { status: 'idle', created: at(0) }));
188
- recordPid('live-0', process.pid);
194
+ recordExecution('live-0', process.pid);
189
195
  for (let i = 0; i < 5; i++) {
190
196
  const id = `term-${i}`;
191
197
  createNode(node(id, { status: 'dead', created: at(10 + i) }));
@@ -4,21 +4,28 @@ import { mkdtempSync, rmSync, mkdirSync } from 'node:fs';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { join } from 'node:path';
6
6
  import { createNode, getNode, setStatus } from '../canvas/canvas.js';
7
- import { closeDb } from '../canvas/db.js';
7
+ import { closeDb, openDb, migrate } from '../canvas/db.js';
8
8
  import { InputError } from '../io.js';
9
9
  import { messageRoutes } from '../../daemon/api/handlers/messages.js';
10
10
  import { pushFinal, FinalizationError } from '../feed/feed.js';
11
11
  import { assertNotFinalized, assertFinalizedForReopen, commitReopen } from '../runtime/reopen.js';
12
12
  import { reviveNode } from '../runtime/revive.js';
13
13
  import { headlessBrokerHost } from '../runtime/host.js';
14
- import { readInboxSince } from '../feed/inbox.js';
14
+ function nodeMailCount(nodeId) {
15
+ return Number(openDb().prepare(`SELECT COUNT(*) AS count FROM deliveries
16
+ WHERE destination_kind = 'node_inbox' AND destination_id = ?`).get(nodeId).count);
17
+ }
15
18
  import { writeGoal } from '../runtime/kickoff.js';
16
19
  import { situationalContextPath } from '../canvas/paths.js';
17
20
  let home;
18
21
  const prevNodeId = process.env['CRTR_NODE_ID'];
19
22
  function node(id) { return { node_id: id, name: id, created: new Date().toISOString(), cwd: '/tmp/work', kind: 'general', mode: 'base', lifecycle: 'terminal', status: 'active' }; }
20
23
  before(() => { home = mkdtempSync(join(tmpdir(), 'crtr-pushfinal-')); process.env['CRTR_HOME'] = home; });
21
- beforeEach(() => { closeDb(); rmSync(home, { recursive: true, force: true }); });
24
+ beforeEach(() => {
25
+ closeDb();
26
+ rmSync(home, { recursive: true, force: true });
27
+ migrate(openDb());
28
+ });
22
29
  after(() => { closeDb(); rmSync(home, { recursive: true, force: true }); delete process.env['CRTR_HOME']; if (prevNodeId === undefined)
23
30
  delete process.env['CRTR_NODE_ID'];
24
31
  else
@@ -66,13 +73,13 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
66
73
  const firstFinal = getNode(id)?.final_report;
67
74
  assert.ok(firstFinal);
68
75
  // A message to the now-finalized node, no --reopen: rejected before the
69
- // handler ever reaches appendInbox/reviveNode. Prove BOTH: the latch is
76
+ // handler ever creates a delivery or reaches reviveNode. Prove BOTH: the latch is
70
77
  // untouched, AND (per #340's Minor finding) no side effect landed first —
71
78
  // spy on the exact revive seam reviveNode calls (headlessBrokerHost.launch,
72
79
  // the same seam revive.test.ts already uses to instrument reviveNode without
73
80
  // a real engine) and assert it was never invoked, plus the inbox is
74
81
  // unchanged.
75
- const inboxBefore = readInboxSince(id, undefined).length;
82
+ const inboxBefore = nodeMailCount(id);
76
83
  const originalLaunch = headlessBrokerHost.launch;
77
84
  let launchCalls = 0;
78
85
  headlessBrokerHost.launch = ((...args) => { launchCalls++; return originalLaunch(...args); });
@@ -84,7 +91,7 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
84
91
  }
85
92
  assert.equal(launchCalls, 0, 'a rejected retask must never attempt a revive');
86
93
  assert.equal(getNode(id)?.final_report, firstFinal, 'a rejected retask must not touch the latch');
87
- assert.equal(readInboxSince(id, undefined).length, inboxBefore, 'a rejected retask must not append an inbox entry');
94
+ assert.equal(nodeMailCount(id), inboxBefore, 'a rejected retask must not create a delivery');
88
95
  // The successful path, driven through the ACTUAL daemon message handler (the
89
96
  // real seam --reopen now lives behind, not a direct call into the gate
90
97
  // internals) — stub the revive seam so no real engine process is spawned,
@@ -105,7 +112,7 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
105
112
  headlessBrokerHost.launch = originalLaunch;
106
113
  }
107
114
  assert.equal(getNode(id)?.final_report, null, '--reopen cleared the latch through the real handler seam');
108
- assert.equal(readInboxSince(id, undefined).length, inboxBefore + 1, 'the re-task message was actually appended to the inbox');
115
+ assert.equal(nodeMailCount(id), inboxBefore + 1, 'the re-task message created one durable delivery');
109
116
  // The re-tasked node can now finish its new mandate and re-latch cleanly.
110
117
  process.env['CRTR_NODE_ID'] = id;
111
118
  await pushFinal(id, 'round 2 verdict');
@@ -15,13 +15,19 @@ import { CrtrClient } from '../../api/client.js';
15
15
  import { createApiServer } from '../../daemon/api/server.js';
16
16
  import registerCanvasStophook from '../../pi-extensions/canvas-stophook.js';
17
17
  import { createNode, getNode, subscribe } from '../canvas/canvas.js';
18
- import { closeDb } from '../canvas/db.js';
18
+ import { beginExecution, recordExecutionPid } from '../canvas/executions.js';
19
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
20
+ import { resetScopeCache } from '../scope.js';
21
+ import { closeScopedStores } from '../scoped-state/db.js';
22
+ import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
19
23
  import { apiSocketPath } from '../canvas/paths.js';
20
24
  import { brokerCapReached, resetFleetForTests } from '../runtime/fleet.js';
21
25
  import { buildPiArgv } from '../runtime/launch.js';
22
26
  import { relaunchRoot } from '../runtime/reset.js';
23
27
  import { bindTestFleet } from './helpers/fleet.js';
24
28
  let home;
29
+ let tf;
30
+ const previousHome = process.env['HOME'];
25
31
  function node(id, over = {}) {
26
32
  return {
27
33
  node_id: id,
@@ -67,16 +73,30 @@ function makeDeps(pid) {
67
73
  }
68
74
  before(() => {
69
75
  home = mkdtempSync(join(tmpdir(), 'crtr-relaunch-'));
70
- process.env['CRTR_HOME'] = home;
76
+ process.env['HOME'] = home;
77
+ process.env['CRTR_HOME'] = join(home, 'canvas');
71
78
  });
72
79
  beforeEach(() => {
73
80
  closeDb();
81
+ closeScopedStores();
74
82
  rmSync(home, { recursive: true, force: true });
83
+ resetScopeCache();
84
+ initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
85
+ migrate(openDb());
86
+ tf = bindTestFleet();
75
87
  });
76
88
  after(() => {
77
89
  closeDb();
90
+ closeScopedStores();
91
+ tf.fleet.dispose();
92
+ resetFleetForTests();
78
93
  rmSync(home, { recursive: true, force: true });
79
94
  delete process.env['CRTR_HOME'];
95
+ if (previousHome === undefined)
96
+ delete process.env['HOME'];
97
+ else
98
+ process.env['HOME'] = previousHome;
99
+ resetScopeCache();
80
100
  });
81
101
  test('relaunchRoot parks the old root done and mints a fresh active root, reaping descendants', async () => {
82
102
  // root → child → grandchild (a parent that subscribes to its workers).
@@ -169,6 +189,10 @@ test('root /new capacity refusal reaches the attached human through broker UI no
169
189
  process.env['CRTR_NODE_ID'] = 'root';
170
190
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
171
191
  const tf = bindTestFleet();
192
+ const executionId = beginExecution('root', { daemonEpoch: tf.fleet.epoch() });
193
+ assert.equal(recordExecutionPid(executionId, 'root', process.pid), 'recorded');
194
+ const previousExecutionId = process.env['CRTR_EXECUTION_ID'];
195
+ process.env['CRTR_EXECUTION_ID'] = executionId;
172
196
  const never = new Promise(() => { });
173
197
  tf.fleet.register('filler-a', { pid: 700_001, exited: never });
174
198
  tf.fleet.register('filler-b', { pid: 700_002, exited: never });
@@ -207,6 +231,10 @@ test('root /new capacity refusal reaches the attached human through broker UI no
207
231
  resetFleetForTests();
208
232
  delete process.env['CRTR_MAX_LIVE_BROKERS'];
209
233
  delete process.env['CRTR_NODE_ID'];
234
+ if (previousExecutionId === undefined)
235
+ delete process.env['CRTR_EXECUTION_ID'];
236
+ else
237
+ process.env['CRTR_EXECUTION_ID'] = previousExecutionId;
210
238
  }
211
239
  });
212
240
  test('relaunchRoot is a no-op for a non-root child and an already-parked root', async () => {
@@ -11,7 +11,9 @@ import assert from 'node:assert/strict';
11
11
  import { mkdtempSync, rmSync } from 'node:fs';
12
12
  import { tmpdir } from 'node:os';
13
13
  import { join } from 'node:path';
14
- import { readConfig, updateConfig } from '../config.js';
14
+ import { ensureScopeInitialized, readConfig, updateConfig } from '../config.js';
15
+ import { closeScopedStores } from '../scoped-state/db.js';
16
+ import { resetScopeCache } from '../scope.js';
15
17
  import { setRelayToken } from '../secrets.js';
16
18
  import { getRemoteCanvasTarget, resolveRemoteCanvasTarget } from '../remote-canvas-target.js';
17
19
  let home;
@@ -22,9 +24,13 @@ before(() => {
22
24
  process.env['HOME'] = home;
23
25
  });
24
26
  beforeEach(() => {
27
+ closeScopedStores();
25
28
  rmSync(home, { recursive: true, force: true });
29
+ resetScopeCache();
30
+ ensureScopeInitialized('user', join(home, '.crouter'));
26
31
  });
27
32
  after(() => {
33
+ closeScopedStores();
28
34
  rmSync(home, { recursive: true, force: true });
29
35
  if (realHome !== undefined)
30
36
  process.env['HOME'] = realHome;
@@ -8,9 +8,11 @@ import assert from 'node:assert/strict';
8
8
  import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
9
9
  import { tmpdir } from 'node:os';
10
10
  import { join } from 'node:path';
11
+ import { ensureScopeInitialized } from '../config.js';
11
12
  import { gitSync } from '../git.js';
12
13
  import { createProfile } from '../profiles/manifest.js';
13
14
  import { loadMemoryStoreView, memoryStoresInPrecedence, openProjectMemoryStore, resolveMemoryDocForTarget, } from '../memory-resolver.js';
15
+ import { closeScopedStores } from '../scoped-state/db.js';
14
16
  import { resetScopeCache } from '../scope.js';
15
17
  const cleanups = [];
16
18
  let previousHome;
@@ -20,8 +22,10 @@ before(() => {
20
22
  beforeEach(() => {
21
23
  process.env.HOME = fixtureDir('crtr-repository-root-identity-home-');
22
24
  resetScopeCache();
25
+ ensureScopeInitialized('user', join(process.env.HOME, '.crouter'));
23
26
  });
24
27
  after(() => {
28
+ closeScopedStores();
25
29
  resetScopeCache();
26
30
  for (const path of cleanups)
27
31
  rmSync(path, { recursive: true, force: true });
@@ -5,11 +5,13 @@
5
5
  // persona keeps the stronger default needed to synthesise a broad review.
6
6
  import { after, before, test } from 'node:test';
7
7
  import assert from 'node:assert/strict';
8
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
8
+ import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
9
9
  import { tmpdir } from 'node:os';
10
10
  import { join } from 'node:path';
11
11
  import { defaultKindsConfig, defaultModelLaddersConfig } from '../../types.js';
12
12
  import { buildLaunchSpec, normalizeModel } from '../runtime/launch.js';
13
+ import { writeRawConfig } from '../config.js';
14
+ import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
13
15
  const priorHome = process.env['HOME'];
14
16
  const ladders = defaultModelLaddersConfig();
15
17
  // Review's own kind default IS its floor — an explicit override weaker than
@@ -20,14 +22,15 @@ before(() => {
20
22
  home = mkdtempSync(join(tmpdir(), 'crtr-review-model-floor-'));
21
23
  process.env['HOME'] = home;
22
24
  mkdirSync(join(home, '.crouter'), { recursive: true });
23
- writeFileSync(join(home, '.crouter', 'config.json'), JSON.stringify({
25
+ initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
26
+ writeRawConfig('user', {
24
27
  kinds: {
25
28
  'audit/reviewers/security': {
26
29
  whenToUse: 'Review one security surface.',
27
30
  model: 'medium',
28
31
  },
29
32
  },
30
- }));
33
+ });
31
34
  });
32
35
  after(() => {
33
36
  if (priorHome === undefined)
@@ -32,7 +32,9 @@ import { join } from 'node:path';
32
32
  import { spawnSync } from 'node:child_process';
33
33
  import { isDisconnected, TERMINAL_BY_CHOICE, listDisconnected } from '../runtime/revive-all.js';
34
34
  import { createNode } from '../canvas/canvas.js';
35
- import { closeDb } from '../canvas/db.js';
35
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
36
+ import { beginExecution, recordExecutionPid } from '../canvas/executions.js';
37
+ import { bindSession } from '../canvas/sessions.js';
36
38
  const ALIVE = () => true;
37
39
  const DEAD = () => false;
38
40
  function meta(over = {}) {
@@ -105,6 +107,7 @@ function deadPid() {
105
107
  return r.pid ?? 0x7ffffffe;
106
108
  }
107
109
  function fabricate(id, over) {
110
+ const { pi_pid, pi_session_id = `uuid-${id}`, pi_session_file = null, ...node } = over;
108
111
  createNode({
109
112
  node_id: id,
110
113
  name: id,
@@ -115,9 +118,15 @@ function fabricate(id, over) {
115
118
  mode: 'base',
116
119
  lifecycle: 'terminal',
117
120
  status: 'active',
118
- pi_session_id: 'uuid-' + id,
119
- ...over,
121
+ ...node,
120
122
  });
123
+ const executionId = beginExecution(id, { daemonEpoch: 'test' });
124
+ if (pi_session_id !== null || pi_session_file !== null) {
125
+ assert.equal(bindSession(id, { executionId, sessionId: pi_session_id, transcriptPath: pi_session_file }), 'bound');
126
+ }
127
+ if (pi_pid !== null && pi_pid !== undefined) {
128
+ assert.equal(recordExecutionPid(executionId, id, pi_pid), 'recorded');
129
+ }
121
130
  closeDb();
122
131
  }
123
132
  before(() => {
@@ -127,6 +136,7 @@ before(() => {
127
136
  beforeEach(() => {
128
137
  closeDb();
129
138
  rmSync(home, { recursive: true, force: true });
139
+ migrate(openDb());
130
140
  });
131
141
  after(() => {
132
142
  closeDb();
@@ -15,7 +15,11 @@ import { tmpdir } from 'node:os';
15
15
  import { join } from 'node:path';
16
16
  import { createNode, getNode } from '../canvas/canvas.js';
17
17
  import { jobDir } from '../canvas/paths.js';
18
- import { closeDb } from '../canvas/db.js';
18
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
19
+ import { resetSession } from '../canvas/sessions.js';
20
+ import { resetScopeCache } from '../scope.js';
21
+ import { closeScopedStores } from '../scoped-state/db.js';
22
+ import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
19
23
  import { bindDaemonEventSource, resetEventSourceForTests } from '../events/source.js';
20
24
  import { resetFleetForTests } from '../runtime/fleet.js';
21
25
  import { CANVAS_EXTENSIONS } from '../runtime/canvas-extensions.js';
@@ -25,6 +29,7 @@ import { deliverNodeMessage } from '../../daemon/messaging/node-message.js';
25
29
  import { bindTestFleet } from './helpers/fleet.js';
26
30
  let home;
27
31
  let tf;
32
+ const previousHome = process.env['HOME'];
28
33
  let seq = 0;
29
34
  const originalLaunch = headlessBrokerHost.launch;
30
35
  /** The real host contract, minus the process: register at the launch seam, so
@@ -37,7 +42,7 @@ function stubLaunch() {
37
42
  };
38
43
  }
39
44
  function node(id, over = {}) {
40
- createNode({
45
+ const meta = {
41
46
  node_id: id,
42
47
  name: id,
43
48
  created: new Date().toISOString(),
@@ -48,7 +53,11 @@ function node(id, over = {}) {
48
53
  status: 'active',
49
54
  host_kind: 'broker',
50
55
  ...over,
51
- });
56
+ };
57
+ createNode(meta);
58
+ if (meta.pi_session_id != null) {
59
+ resetSession(id, { sessionId: meta.pi_session_id, transcriptPath: meta.pi_session_file ?? null });
60
+ }
52
61
  return id;
53
62
  }
54
63
  /** Fill the ledger to the cap with live brokers. */
@@ -59,12 +68,19 @@ async function saturate() {
59
68
  }
60
69
  before(() => {
61
70
  home = mkdtempSync(join(tmpdir(), 'crtr-revive-capacity-'));
62
- process.env['CRTR_HOME'] = home;
71
+ process.env['HOME'] = home;
72
+ process.env['CRTR_HOME'] = join(home, 'canvas');
63
73
  process.env['CRTR_MAX_LIVE_BROKERS'] = '2';
64
74
  resetEventSourceForTests();
65
75
  bindDaemonEventSource();
66
76
  });
67
77
  beforeEach(() => {
78
+ closeDb();
79
+ closeScopedStores();
80
+ rmSync(home, { recursive: true, force: true });
81
+ resetScopeCache();
82
+ initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
83
+ migrate(openDb());
68
84
  tf = bindTestFleet();
69
85
  stubLaunch();
70
86
  });
@@ -74,9 +90,15 @@ after(() => {
74
90
  resetFleetForTests();
75
91
  resetEventSourceForTests();
76
92
  closeDb();
93
+ closeScopedStores();
77
94
  delete process.env['CRTR_MAX_LIVE_BROKERS'];
78
95
  delete process.env['CRTR_HOME'];
96
+ if (previousHome === undefined)
97
+ delete process.env['HOME'];
98
+ else
99
+ process.env['HOME'] = previousHome;
79
100
  rmSync(home, { recursive: true, force: true });
101
+ resetScopeCache();
80
102
  });
81
103
  test('a refusing caller gets an error naming the cap and the live count, never a silent no-op', async () => {
82
104
  await saturate();
@@ -11,9 +11,14 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
11
11
  import { tmpdir } from 'node:os';
12
12
  import { join } from 'node:path';
13
13
  import { createNode, getNode } from '../canvas/canvas.js';
14
+ import { ensureScopeInitialized } from '../config.js';
15
+ import { closeScopedStores } from '../scoped-state/db.js';
14
16
  import { contextDir } from '../canvas/paths.js';
15
- import { closeDb } from '../canvas/db.js';
16
- import { appendInbox, readCursor, writeCursor } from '../feed/inbox.js';
17
+ import { closeDb, migrate, openDb } from '../canvas/db.js';
18
+ import { enqueueNodeMail } from '../feed/messages.js';
19
+ import { acknowledgeNodeMail, acknowledgedNodeMailCount, claimNodeMail } from '../canvas/deliveries.js';
20
+ import { beginExecution, endExecution } from '../canvas/executions.js';
21
+ import { bindSession } from '../canvas/sessions.js';
17
22
  import { transition } from '../runtime/lifecycle.js';
18
23
  import { reviveNode } from '../runtime/revive.js';
19
24
  import { headlessBrokerHost } from '../runtime/host.js';
@@ -21,6 +26,7 @@ import { resetFleetForTests } from '../runtime/fleet.js';
21
26
  import { bindTestFleet } from './helpers/fleet.js';
22
27
  let home;
23
28
  let priorHome;
29
+ let priorUserHome;
24
30
  let fleet;
25
31
  let launches;
26
32
  let originalLaunch;
@@ -42,6 +48,9 @@ function parkResident(id, ground = {}) {
42
48
  pi_session_file: sessionFile,
43
49
  };
44
50
  createNode(meta);
51
+ const executionId = beginExecution(id, { daemonEpoch: 'test' });
52
+ assert.equal(bindSession(id, { executionId, sessionId: meta.pi_session_id, transcriptPath: sessionFile }), 'bound');
53
+ endExecution(executionId, { reason: 'parked test setup' });
45
54
  mkdirSync(contextDir(id), { recursive: true });
46
55
  if (ground.roadmap !== undefined)
47
56
  writeFileSync(join(contextDir(id), 'roadmap.md'), ground.roadmap);
@@ -52,7 +61,7 @@ function parkResident(id, ground = {}) {
52
61
  /** Durable wake-worthy mail, appended exactly as every message doorway appends
53
62
  * it before calling reviveNode. */
54
63
  function deliverMail(id, tier = 'normal') {
55
- return appendInbox(id, { from: null, tier, kind: 'message', label: 'work', data: { body: 'work' } }).entry_id;
64
+ return enqueueNodeMail(id, { kind: 'message', label: 'work', bodyJson: { body: 'work' }, urgency: tier, wake: 1 });
56
65
  }
57
66
  /** Did this launch carry the fresh-revive kickoff? `buildReviveKickoff` always
58
67
  * opens its card body with this sentence (src/core/runtime/kickoff.ts:325). */
@@ -67,12 +76,16 @@ function placements() {
67
76
  before(() => {
68
77
  home = mkdtempSync(join(tmpdir(), 'crtr-revive-parked-'));
69
78
  priorHome = process.env['CRTR_HOME'];
79
+ priorUserHome = process.env['HOME'];
70
80
  process.env['CRTR_HOME'] = home;
81
+ process.env['HOME'] = home;
71
82
  });
72
83
  beforeEach(() => {
73
84
  closeDb();
74
85
  rmSync(home, { recursive: true, force: true });
75
86
  mkdirSync(home, { recursive: true });
87
+ ensureScopeInitialized('user', join(home, '.crouter'));
88
+ migrate(openDb());
76
89
  resetFleetForTests();
77
90
  fleet = bindTestFleet();
78
91
  launches = [];
@@ -87,6 +100,7 @@ beforeEach(() => {
87
100
  afterEach(() => {
88
101
  headlessBrokerHost.launch = originalLaunch;
89
102
  closeDb();
103
+ closeScopedStores();
90
104
  resetFleetForTests();
91
105
  });
92
106
  after(() => {
@@ -95,6 +109,10 @@ after(() => {
95
109
  delete process.env['CRTR_HOME'];
96
110
  else
97
111
  process.env['CRTR_HOME'] = priorHome;
112
+ if (priorUserHome === undefined)
113
+ delete process.env['HOME'];
114
+ else
115
+ process.env['HOME'] = priorUserHome;
98
116
  });
99
117
  test('a parked node with mail waiting resumes its main transcript and clears the marker', async () => {
100
118
  parkResident('parked', { roadmap: '# Roadmap\n\n- one open item\n' });
@@ -120,7 +138,7 @@ test('an input-less revival of a parked node quietly resumes and injects no kick
120
138
  assert.equal(result.resumed, true, 'nothing arrived, so there is nothing a fresh window would answer');
121
139
  assert.deepEqual(placements(), [{ nodeId: 'quiet', resuming: true }]);
122
140
  assert.equal(kickedOff(launches[0]), false, 'a quiet resume generates nothing');
123
- assert.equal(readCursor('quiet'), undefined, 'drainBearings did not run, so nothing was consumed');
141
+ assert.equal(acknowledgedNodeMailCount('quiet'), 0, 'a quiet resume does not acknowledge mail');
124
142
  const reopened = getNode('quiet');
125
143
  assert.equal(reopened.status, 'active');
126
144
  assert.equal(reopened.intent ?? null, null, 'the park marker clears on a quiet resume too');
@@ -130,12 +148,17 @@ test('deferred mail alone is not input, so the revival still resumes quietly', a
130
148
  deliverMail('deferred', 'deferred');
131
149
  assert.equal((await reviveNode('deferred', { resume: true, capacity: 'freeze' })).resumed, true);
132
150
  assert.equal(kickedOff(launches[0]), false);
133
- assert.equal(readCursor('deferred'), undefined, 'the deferred entry rides the next natural cycle, unconsumed');
151
+ assert.equal(acknowledgedNodeMailCount('deferred'), 0, 'the deferred delivery rides the next natural cycle, unacknowledged');
134
152
  });
135
- test('mail already covered by the cursor is not input, so the revival still resumes quietly', async () => {
153
+ test('mail already acknowledged by an earlier execution is not input, so the revival still resumes quietly', async () => {
136
154
  parkResident('stale', { roadmap: '# Roadmap\n\n- one open item\n' });
137
- writeCursor('stale', deliverMail('stale'));
138
- assert.equal((await reviveNode('stale', { resume: true, capacity: 'freeze' })).resumed, true, 'only the UNSEEN suffix counts as input');
155
+ const delivery = deliverMail('stale');
156
+ const executionId = beginExecution('stale', { daemonEpoch: 'test' });
157
+ const claim = claimNodeMail('stale', executionId, 'wake');
158
+ assert.equal(claim.deliveries.length, 1, 'the earlier execution claims the delivery');
159
+ assert.deepEqual(acknowledgeNodeMail('stale', executionId, [{ deliveryId: delivery.deliveryId, attempts: claim.deliveries[0].attempts, disposition: 'acknowledged' }]).results, [{ deliveryId: delivery.deliveryId, outcome: 'acknowledged' }], 'the prior handoff has an explicit SQL acknowledgement');
160
+ endExecution(executionId, { reason: 'test complete' });
161
+ assert.equal((await reviveNode('stale', { resume: true, capacity: 'freeze' })).resumed, true, 'only pending wake deliveries count as input');
139
162
  assert.equal(kickedOff(launches[0]), false);
140
163
  });
141
164
  test('a parked node with no goal and no roadmap resumes its transcript rather than waking amnesiac', async () => {
@@ -65,7 +65,7 @@ const brokerPid = () => h.node(id).pi_pid;
65
65
  // engine AND the streaming AgentSessionEvents are fanned out to the client
66
66
  // VERBATIM. Failure mode: a broken relay/fan-out (viewer sees nothing).
67
67
  test('G1 — controller prompt runs the engine and the streamed AgentSessionEvents relay to the client', async () => {
68
- const c = await ctrl('g1-ctrl');
68
+ const c = await attachUntil(id, 'controller', 'g1-ctrl', (a) => a.welcome.role === 'controller' && a.welcome.snapshot.state.isStreaming === false, 'G1 controller admitted while the engine is idle');
69
69
  assert.equal(c.welcome.role, 'controller', 'first controller is admitted as controller');
70
70
  const token = tok('G1-PROMPT');
71
71
  c.send({ type: 'prompt', text: token });
@@ -14,8 +14,9 @@ import { after, before, test } from 'node:test';
14
14
  import assert from 'node:assert/strict';
15
15
  import { createNode } from '../../canvas/canvas.js';
16
16
  import { closeDb } from '../../canvas/db.js';
17
+ import { resetSession } from '../../canvas/sessions.js';
17
18
  import { isPidAlive } from '../../canvas/pid.js';
18
- import { appendInbox } from '../../feed/inbox.js';
19
+ import { enqueueNodeMail } from '../../feed/messages.js';
19
20
  import { closeNode } from '../../runtime/close.js';
20
21
  import { headlessBrokerHost } from '../../runtime/host.js';
21
22
  import { transition } from '../../runtime/lifecycle.js';
@@ -116,7 +117,7 @@ test('a birth at the cap freezes instead of booting, survives saturated ticks, a
116
117
  await h.awaitFleetExit(second);
117
118
  const filler = await h.spawnHeadlessChild(root, 'terminal thaw filler');
118
119
  assert.equal(h.fleet.size(), 2, 'the parked target is non-live while the cap remains full');
119
- appendInbox(second, { from: root, tier: 'normal', kind: 'message', label: 'durable wake' });
120
+ enqueueNodeMail(second, { senderNodeId: root, kind: 'message', label: 'durable wake', urgency: 'normal', wake: 1 });
120
121
  assert.equal((await reviveNode(second, { resume: true, capacity: 'freeze' })).outcome, 'frozen');
121
122
  closeDb();
122
123
  const frozenTerminal = h.node(second);
@@ -142,8 +143,8 @@ test('a birth at the cap freezes instead of booting, survives saturated ticks, a
142
143
  host_kind: 'broker',
143
144
  parent: root,
144
145
  created: new Date().toISOString(),
145
- pi_session_id: 'resident-drain-session',
146
146
  });
147
+ resetSession('resident-drain', { sessionId: 'resident-drain-session', transcriptPath: null });
147
148
  assert.equal((await reviveNode('resident-drain', { resume: true, capacity: 'freeze' })).outcome, 'frozen');
148
149
  await h.tick();
149
150
  closeDb();