@north-light/crouter 0.3.311 → 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 (520) 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 +17 -5
  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 +312 -1
  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 +62 -19
  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 +4 -3
  140. package/dist/core/__tests__/on-read-dedup-resume.test.js +8 -7
  141. package/dist/core/__tests__/on-read-nested-store.test.js +8 -7
  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 +35 -32
  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 +5 -4
  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 +19 -5
  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/command-hooks/artifact.d.ts +6 -0
  217. package/dist/core/command-hooks/artifact.js +22 -6
  218. package/dist/core/command-hooks/discovery.d.ts +2 -0
  219. package/dist/core/command-hooks/discovery.js +2 -0
  220. package/dist/core/command-hooks/lifecycle-catalog.d.ts +20 -2
  221. package/dist/core/command-hooks/lifecycle-catalog.js +7 -2
  222. package/dist/core/command-hooks/lifecycle-create.d.ts +4 -0
  223. package/dist/core/command-hooks/lifecycle-create.js +51 -0
  224. package/dist/core/command-hooks/schema.d.ts +2 -2
  225. package/dist/core/command-hooks/schema.js +5 -4
  226. package/dist/core/command-hooks/transport/exec-invoke.js +3 -1
  227. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +18 -8
  228. package/dist/core/command-hooks/transport/exec-lifecycle.js +89 -30
  229. package/dist/core/config.d.ts +17 -12
  230. package/dist/core/config.js +106 -155
  231. package/dist/core/errors.d.ts +1 -0
  232. package/dist/core/errors.js +4 -0
  233. package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
  234. package/dist/core/feed/feed.d.ts +0 -6
  235. package/dist/core/feed/feed.js +68 -56
  236. package/dist/core/feed/inbox.d.ts +7 -81
  237. package/dist/core/feed/inbox.js +46 -378
  238. package/dist/core/feed/messages.d.ts +58 -0
  239. package/dist/core/feed/messages.js +217 -0
  240. package/dist/core/fs-utils.d.ts +4 -0
  241. package/dist/core/fs-utils.js +21 -1
  242. package/dist/core/human/answer.d.ts +1 -1
  243. package/dist/core/human/answer.js +1 -1
  244. package/dist/core/human/claim.d.ts +1 -1
  245. package/dist/core/human/claim.js +2 -4
  246. package/dist/core/human/component-docs.js +1 -1
  247. package/dist/core/human/feedback-companion.js +4 -3
  248. package/dist/core/human/feedback.d.ts +5 -8
  249. package/dist/core/human/feedback.js +57 -85
  250. package/dist/core/human/page-authoring.d.ts +30 -0
  251. package/dist/core/human/page-authoring.js +19 -0
  252. package/dist/core/human/requests.d.ts +136 -0
  253. package/dist/core/human/requests.js +515 -0
  254. package/dist/core/human/root.d.ts +0 -7
  255. package/dist/core/human/root.js +0 -17
  256. package/dist/core/human/scan.d.ts +2 -7
  257. package/dist/core/human/scan.js +48 -132
  258. package/dist/core/human/summary.d.ts +1 -1
  259. package/dist/core/human/summary.js +1 -1
  260. package/dist/core/human/tickets.d.ts +23 -83
  261. package/dist/core/human/tickets.js +92 -243
  262. package/dist/core/human/types.d.ts +5 -1
  263. package/dist/core/installed-plugins.js +8 -3
  264. package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
  265. package/dist/core/locked-file.d.ts +6 -3
  266. package/dist/core/locked-file.js +36 -9
  267. package/dist/core/memory/extensions.js +2 -0
  268. package/dist/core/preview-registry.js +0 -1
  269. package/dist/core/profiles/__tests__/env-store.test.js +2 -0
  270. package/dist/core/profiles/default-binding.d.ts +0 -4
  271. package/dist/core/profiles/default-binding.js +12 -58
  272. package/dist/core/profiles/env-store.js +8 -3
  273. package/dist/core/profiles/manifest.d.ts +2 -37
  274. package/dist/core/profiles/manifest.js +35 -161
  275. package/dist/core/profiles/select.js +3 -0
  276. package/dist/core/review/__tests__/capture-origin.test.js +13 -2
  277. package/dist/core/review/__tests__/comments.test.js +28 -10
  278. package/dist/core/review/__tests__/remap.test.js +28 -10
  279. package/dist/core/review/__tests__/stage-identity.test.js +17 -7
  280. package/dist/core/review/birth.d.ts +1 -1
  281. package/dist/core/review/birth.js +34 -5
  282. package/dist/core/review/comments.js +1 -1
  283. package/dist/core/review/companion.d.ts +1 -1
  284. package/dist/core/review/companion.js +2 -2
  285. package/dist/core/review/document.js +1 -1
  286. package/dist/core/review/project.d.ts +5 -1
  287. package/dist/core/review/project.js +14 -36
  288. package/dist/core/review/realize.d.ts +3 -6
  289. package/dist/core/review/realize.js +51 -168
  290. package/dist/core/review/remap.js +1 -1
  291. package/dist/core/review/stage.d.ts +3 -2
  292. package/dist/core/review/stage.js +2 -3
  293. package/dist/core/review/store.d.ts +3 -21
  294. package/dist/core/review/store.js +140 -186
  295. package/dist/core/review/types.d.ts +0 -1
  296. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
  297. package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
  298. package/dist/core/runtime/broker/auth-reload.js +9 -10
  299. package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
  300. package/dist/core/runtime/broker/daemon-ops.js +42 -9
  301. package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
  302. package/dist/core/runtime/broker/extension-abort.js +11 -0
  303. package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
  304. package/dist/core/runtime/broker/fault-retry.js +142 -95
  305. package/dist/core/runtime/broker/inbox.d.ts +4 -32
  306. package/dist/core/runtime/broker/inbox.js +4 -92
  307. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  308. package/dist/core/runtime/broker/rebind.js +21 -12
  309. package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
  310. package/dist/core/runtime/broker-persona-guidance.js +2 -13
  311. package/dist/core/runtime/broker.js +28 -22
  312. package/dist/core/runtime/close.d.ts +3 -9
  313. package/dist/core/runtime/close.js +16 -27
  314. package/dist/core/runtime/fault.d.ts +3 -93
  315. package/dist/core/runtime/fault.js +9 -419
  316. package/dist/core/runtime/kickoff.d.ts +3 -6
  317. package/dist/core/runtime/kickoff.js +12 -18
  318. package/dist/core/runtime/launch.js +1 -1
  319. package/dist/core/runtime/lifecycle.js +40 -7
  320. package/dist/core/runtime/nodes.d.ts +5 -1
  321. package/dist/core/runtime/nodes.js +26 -11
  322. package/dist/core/runtime/placement.js +2 -2
  323. package/dist/core/runtime/recycle.js +24 -14
  324. package/dist/core/runtime/reset.js +26 -7
  325. package/dist/core/runtime/revive.js +226 -217
  326. package/dist/core/runtime/spawn.d.ts +4 -1
  327. package/dist/core/runtime/spawn.js +43 -5
  328. package/dist/core/runtime/warm-pool.d.ts +2 -2
  329. package/dist/core/runtime/warm-pool.js +23 -3
  330. package/dist/core/scoped-state/db.d.ts +7 -0
  331. package/dist/core/scoped-state/db.js +92 -0
  332. package/dist/core/scoped-state/migrate.d.ts +11 -0
  333. package/dist/core/scoped-state/migrate.js +198 -0
  334. package/dist/core/scoped-state/paths.d.ts +9 -0
  335. package/dist/core/scoped-state/paths.js +27 -0
  336. package/dist/core/scoped-state/profiles.d.ts +12 -0
  337. package/dist/core/scoped-state/profiles.js +62 -0
  338. package/dist/core/scoped-state/providers.d.ts +16 -0
  339. package/dist/core/scoped-state/providers.js +8 -0
  340. package/dist/core/scoped-state/schema.d.ts +3 -0
  341. package/dist/core/scoped-state/schema.js +26 -0
  342. package/dist/core/scoped-state/settings.d.ts +28 -0
  343. package/dist/core/scoped-state/settings.js +82 -0
  344. package/dist/core/subscription-state.d.ts +29 -48
  345. package/dist/core/subscription-state.js +176 -712
  346. package/dist/core/worktree-close.js +4 -4
  347. package/dist/core/worktree-mutation-async.js +2 -2
  348. package/dist/core/worktree-sweep.js +11 -16
  349. package/dist/core/worktree.js +6 -12
  350. package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
  351. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
  352. package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
  353. package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
  354. package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
  355. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +41 -17
  356. package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
  357. package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
  358. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
  359. package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
  360. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
  361. package/dist/daemon/api/__tests__/model-config.test.js +8 -8
  362. package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
  363. package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
  364. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
  365. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +6 -3
  366. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
  367. package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
  368. package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
  369. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
  370. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
  371. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +29 -43
  372. package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
  373. package/dist/daemon/api/bridge.js +1 -1
  374. package/dist/daemon/api/handlers/bash-jobs.js +6 -7
  375. package/dist/daemon/api/handlers/broker-ops.js +47 -84
  376. package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
  377. package/dist/daemon/api/handlers/broker-recovery.js +251 -0
  378. package/dist/daemon/api/handlers/canvas.js +2 -44
  379. package/dist/daemon/api/handlers/daemon.js +41 -0
  380. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  381. package/dist/daemon/api/handlers/health.js +10 -5
  382. package/dist/daemon/api/handlers/human-requests.js +168 -188
  383. package/dist/daemon/api/handlers/human.js +3 -148
  384. package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
  385. package/dist/daemon/api/handlers/inbox-page.js +89 -0
  386. package/dist/daemon/api/handlers/inbox.js +21 -120
  387. package/dist/daemon/api/handlers/messages.d.ts +1 -0
  388. package/dist/daemon/api/handlers/messages.js +73 -15
  389. package/dist/daemon/api/handlers/node-outcomes.js +58 -13
  390. package/dist/daemon/api/handlers/nodes.d.ts +1 -0
  391. package/dist/daemon/api/handlers/nodes.js +41 -42
  392. package/dist/daemon/api/handlers/reviews.js +4 -29
  393. package/dist/daemon/api/map.d.ts +25 -3
  394. package/dist/daemon/api/map.js +84 -14
  395. package/dist/daemon/api/server.js +68 -9
  396. package/dist/daemon/control.d.ts +18 -0
  397. package/dist/daemon/cron/disposition.d.ts +2 -0
  398. package/dist/daemon/cron/disposition.js +8 -5
  399. package/dist/daemon/cron/settle.js +37 -13
  400. package/dist/daemon/cron/sinks.d.ts +18 -1
  401. package/dist/daemon/cron/sinks.js +47 -93
  402. package/dist/daemon/crtrd-cli.js +4 -19
  403. package/dist/daemon/crtrd.d.ts +2 -0
  404. package/dist/daemon/crtrd.js +206 -81
  405. package/dist/daemon/fleet.js +5 -6
  406. package/dist/daemon/human/finish.d.ts +12 -24
  407. package/dist/daemon/human/finish.js +88 -285
  408. package/dist/daemon/human/settle.d.ts +40 -0
  409. package/dist/daemon/human/settle.js +89 -0
  410. package/dist/daemon/human/sweep.d.ts +20 -5
  411. package/dist/daemon/human/sweep.js +56 -60
  412. package/dist/daemon/manage.d.ts +21 -16
  413. package/dist/daemon/manage.js +85 -51
  414. package/dist/daemon/messaging/node-message.d.ts +1 -1
  415. package/dist/daemon/messaging/node-message.js +9 -12
  416. package/dist/daemon/park-activity.js +3 -3
  417. package/dist/daemon/reconcilers/bash-deadline.js +6 -7
  418. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  419. package/dist/daemon/reconcilers/broker-supervision.js +41 -19
  420. package/dist/daemon/reconcilers/controller-death.js +6 -18
  421. package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
  422. package/dist/daemon/reconcilers/delivery-lane.js +130 -0
  423. package/dist/daemon/reconcilers/live-obligation.js +3 -3
  424. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  425. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
  426. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
  427. package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
  428. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  429. package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
  430. package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
  431. package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
  432. package/dist/daemon/review/companion.js +5 -11
  433. package/dist/daemon/review/deliver.d.ts +1 -5
  434. package/dist/daemon/review/deliver.js +3 -52
  435. package/dist/daemon/review/finish.d.ts +2 -27
  436. package/dist/daemon/review/finish.js +79 -263
  437. package/dist/daemon/review/sweep.d.ts +3 -10
  438. package/dist/daemon/review/sweep.js +13 -131
  439. package/dist/daemon/startup-policy.d.ts +0 -5
  440. package/dist/daemon/startup-policy.js +0 -5
  441. package/dist/hook-authoring.d.ts +28 -2
  442. package/dist/hook-authoring.js +53 -1
  443. package/dist/index.d.ts +3 -2
  444. package/dist/index.js +1 -1
  445. package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
  446. package/dist/migrations/__tests__/activation.test.js +9 -6
  447. package/dist/migrations/activation.d.ts +3 -2
  448. package/dist/migrations/activation.js +2 -4
  449. package/dist/migrations/corpus.d.ts +2 -5
  450. package/dist/migrations/corpus.js +9 -20
  451. package/dist/migrations/runner.d.ts +3 -1
  452. package/dist/migrations/runner.js +6 -2
  453. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
  454. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
  455. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
  456. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
  457. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
  458. package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
  459. package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
  460. package/dist/pi-extensions/canvas-passive-context.js +85 -37
  461. package/dist/pi-extensions/canvas-stophook.js +47 -31
  462. package/dist/shared/env.d.ts +1 -0
  463. package/dist/shared/env.js +3 -0
  464. package/package.json +1 -1
  465. package/runtime.lock.json +5 -5
  466. package/dist/clients/attach/__tests__/page-block.test.js +0 -54
  467. package/dist/clients/inbox/review-visibility.d.ts +0 -5
  468. package/dist/clients/inbox/review-visibility.js +0 -19
  469. package/dist/commands/canvas-rebuild-index.d.ts +0 -2
  470. package/dist/commands/canvas-rebuild-index.js +0 -46
  471. package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
  472. package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
  473. package/dist/core/__tests__/human-deliver.test.js +0 -256
  474. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
  475. package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
  476. package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
  477. package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
  478. package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
  479. package/dist/core/__tests__/phase4-review-store.test.js +0 -144
  480. package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
  481. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
  482. package/dist/core/canvas/human-deliveries.d.ts +0 -39
  483. package/dist/core/canvas/human-deliveries.js +0 -75
  484. package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
  485. package/dist/core/canvas/node-outcome-deliveries.js +0 -159
  486. package/dist/core/feed/passive.d.ts +0 -3
  487. package/dist/core/feed/passive.js +0 -53
  488. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
  489. package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
  490. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
  491. package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
  492. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
  493. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
  494. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
  495. package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
  496. package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
  497. package/dist/core/human/__tests__/page-tickets.test.js +0 -161
  498. package/dist/core/review/ticket-filter.d.ts +0 -17
  499. package/dist/core/review/ticket-filter.js +0 -21
  500. package/dist/core/runtime/broker/passive.d.ts +0 -17
  501. package/dist/core/runtime/broker/passive.js +0 -44
  502. package/dist/core/runtime/busy.d.ts +0 -46
  503. package/dist/core/runtime/busy.js +0 -150
  504. package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
  505. package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
  506. package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
  507. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
  508. package/dist/daemon/human/deliver-action.d.ts +0 -3
  509. package/dist/daemon/human/deliver-action.js +0 -9
  510. package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
  511. package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
  512. package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
  513. package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
  514. package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
  515. package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
  516. package/dist/daemon/startup-block-marker.d.ts +0 -25
  517. package/dist/daemon/startup-block-marker.js +0 -99
  518. /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
  519. /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
  520. /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ import type { DaemonAdmitDTO, StartupPhaseDTO } from '../api/dto/health.js';
1
2
  /** What crtrd exposes to handlers that act on the daemon process itself. */
2
3
  export interface DaemonControl {
3
4
  /** This daemon's epoch id. */
@@ -14,6 +15,23 @@ export interface DaemonControl {
14
15
  };
15
16
  /** Register daemon-owned post-response work for shutdown draining. */
16
17
  registerDetached(work: Promise<void>): void;
18
+ /** Null only after normal startup completed. */
19
+ startupBlock(): {
20
+ phase: Exclude<StartupPhaseDTO, 'ready'>;
21
+ message: string;
22
+ blockerPaths: readonly string[];
23
+ } | null;
24
+ /** Admit normal work after the daemon has prepared its storage. */
25
+ admitStartup(): Promise<DaemonAdmitDTO>;
26
+ /** Re-run daemon-owned corpus migration and resume normal startup when repaired. */
27
+ repairMigrations(req: {
28
+ dryRun: boolean;
29
+ dirs: readonly string[];
30
+ }): Promise<{
31
+ result: import('../migrations/runner.js').OnDiskMigrationRunResult;
32
+ resumed: boolean;
33
+ resumeError?: string;
34
+ }>;
17
35
  }
18
36
  /** Bind this process's control surface. Called once, by `runDaemon`. */
19
37
  export declare function bindDaemonControl(control: DaemonControl): void;
@@ -1,4 +1,5 @@
1
1
  import { type Cron } from '../../core/canvas/crons.js';
2
+ import { type CronSinkResolution } from './sinks.js';
2
3
  export interface RunSettleContext {
3
4
  runId: string;
4
5
  startedAtIso: string;
@@ -15,5 +16,6 @@ export interface Disposition {
15
16
  delivered: string;
16
17
  /** A paused row is retained so `cron resume` can re-arm it. */
17
18
  paused: boolean;
19
+ obligation?: CronSinkResolution;
18
20
  }
19
21
  export declare function disposeSettledRun(c: Cron, ctx: RunSettleContext, outOfBand: boolean, selfCanceled?: boolean): Promise<Disposition>;
@@ -1,6 +1,6 @@
1
1
  import { getCron, setCronLastOutputHash } from '../../core/canvas/crons.js';
2
2
  import { escalateFailure, failureSummary } from './escalation.js';
3
- import { deliverToSink } from './sinks.js';
3
+ import { resolveCronSink } from './sinks.js';
4
4
  export async function disposeSettledRun(c, ctx, outOfBand, selfCanceled = false) {
5
5
  const prefix = outOfBand ? 'out-of-band: ' : '';
6
6
  // A self-cancel still delivers its already-produced output; an external cancellation does not.
@@ -31,17 +31,20 @@ export async function disposeSettledRun(c, ctx, outOfBand, selfCanceled = false)
31
31
  case 'on-change':
32
32
  if (!changed)
33
33
  return { delivered: `${prefix}unchanged — not delivered (on-change)`, paused: false };
34
- return deliverOrEscalate(effective, ctx, outOfBand, prefix);
34
+ return resolveOrEscalate(effective, ctx, outOfBand, prefix);
35
35
  case 'always':
36
- return deliverOrEscalate(effective, ctx, outOfBand, prefix);
36
+ return resolveOrEscalate(effective, ctx, outOfBand, prefix);
37
37
  }
38
38
  }
39
- async function deliverOrEscalate(c, ctx, outOfBand, prefix) {
39
+ async function resolveOrEscalate(c, ctx, outOfBand, prefix) {
40
40
  if (ctx.stdoutHead.trim() === '') {
41
41
  return { delivered: `${prefix}empty stdout — nothing delivered`, paused: false };
42
42
  }
43
43
  try {
44
- return { delivered: `${prefix}${await deliverToSink(c, ctx.stdoutHead)}`, paused: false };
44
+ const obligation = resolveCronSink(c, ctx.runId, ctx.stdoutHead);
45
+ return obligation.kind === 'none'
46
+ ? { delivered: `${prefix}${obligation.delivered}`, paused: false }
47
+ : { delivered: '', paused: false, obligation };
45
48
  }
46
49
  catch (err) {
47
50
  const why = `delivery failed: ${err.message}`;
@@ -1,4 +1,6 @@
1
- import { consumeCron, recordCronRun, releaseCronRunLease, } from '../../core/canvas/crons.js';
1
+ import { consumeCron, recordCronRunLocked, releaseCronRunLease, } from '../../core/canvas/crons.js';
2
+ import { withCanvasWrite } from '../../core/canvas/db.js';
3
+ import { enqueueExternalAction, enqueueNodeMail } from '../../core/feed/messages.js';
2
4
  import { disposeSettledRun } from './disposition.js';
3
5
  function occurrenceStaysOwed(lease) {
4
6
  return typeof lease === 'object' && (lease.kind === 'park' || lease.kind === 'redue');
@@ -7,27 +9,49 @@ export async function settleRun(c, input) {
7
9
  const { outOfBand, outcome, record, lease } = input;
8
10
  let delivered;
9
11
  let paused;
12
+ let obligation;
10
13
  if (outcome.kind === 'disposed') {
11
14
  const disposition = await disposeSettledRun(c, outcome.ctx, outOfBand, outcome.selfCanceled ?? false);
12
15
  delivered = disposition.delivered;
13
16
  paused = disposition.paused;
17
+ obligation = disposition.obligation;
14
18
  }
15
19
  else {
16
20
  delivered = outcome.delivered;
17
21
  paused = outcome.paused ?? false;
18
22
  }
19
- const written = {
20
- run_id: record.runId,
21
- cron_id: c.cron_id,
22
- started: record.startedAtIso,
23
- finished: new Date(record.finishedAtMs).toISOString(),
24
- duration_ms: record.durationMs,
25
- exit_code: record.exitCode,
26
- stdout_head: record.stdoutHead,
27
- stderr_head: record.stderrHead,
28
- delivered,
29
- };
30
- recordCronRun(written);
23
+ const written = withCanvasWrite((db) => {
24
+ if (obligation !== undefined) {
25
+ if (obligation.kind === 'node') {
26
+ const enqueued = enqueueNodeMail(obligation.destinationNodeId, {
27
+ kind: 'message', label: obligation.label, senderNodeId: obligation.senderNodeId,
28
+ bodyJson: { body: obligation.stdout }, urgency: obligation.urgency, wake: 1,
29
+ idempotencyKey: record.runId,
30
+ });
31
+ delivered = `delivered: ${enqueued.deliveryId}`;
32
+ }
33
+ else if (obligation.kind === 'external') {
34
+ const enqueued = enqueueExternalAction({
35
+ destinationId: obligation.destinationId, adapter: obligation.adapter,
36
+ bodyJson: obligation.bodyJson, idempotencyKey: record.runId,
37
+ });
38
+ delivered = `delivered: ${enqueued.deliveryId}`;
39
+ }
40
+ }
41
+ const entry = {
42
+ run_id: record.runId,
43
+ cron_id: c.cron_id,
44
+ started: record.startedAtIso,
45
+ finished: new Date(record.finishedAtMs).toISOString(),
46
+ duration_ms: record.durationMs,
47
+ exit_code: record.exitCode,
48
+ stdout_head: record.stdoutHead,
49
+ stderr_head: record.stderrHead,
50
+ delivered,
51
+ };
52
+ recordCronRunLocked(db, entry);
53
+ return entry;
54
+ });
31
55
  if (lease !== 'none')
32
56
  releaseCronRunLease(c.cron_id, lease === 'release' ? undefined : lease);
33
57
  // Retain out-of-band, paused, and held rows; their occurrence is not spent.
@@ -1,2 +1,19 @@
1
1
  import { type Cron } from '../../core/canvas/crons.js';
2
- export declare function deliverToSink(c: Cron, stdout: string): Promise<string>;
2
+ export type CronSinkResolution = {
3
+ kind: 'none';
4
+ delivered: string;
5
+ } | {
6
+ kind: 'node';
7
+ destinationNodeId: string;
8
+ senderNodeId: string | null;
9
+ label: string;
10
+ stdout: string;
11
+ urgency: 'critical' | 'urgent' | 'normal' | 'deferred';
12
+ } | {
13
+ kind: 'external';
14
+ destinationId: string;
15
+ adapter: Record<string, unknown>;
16
+ bodyJson: unknown;
17
+ };
18
+ /** Resolve a completed run into a durable obligation. No sink effect happens here. */
19
+ export declare function resolveCronSink(c: Cron, runId: string, stdout: string): CronSinkResolution;
@@ -1,105 +1,59 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { rmSync } from 'node:fs';
3
- import { synthesizedPageDocument, writeSynthesizedPage } from '../../core/human/page-synth.js';
4
- import { ticketDir } from '../../core/human/root.js';
5
- import { preparePage, publishPage } from '../../core/human/tickets.js';
6
- import { resolvePageComponents } from '../../core/config.js';
1
+ import { newNodeId } from '../../core/runtime/nodes.js';
7
2
  import { getNode } from '../../core/canvas/canvas.js';
8
- import { cancelCronsOnWake } from '../../core/canvas/crons.js';
9
- import { appendInbox } from '../../core/feed/inbox.js';
3
+ import { parseCronSink } from '../../core/canvas/crons.js';
10
4
  import { hasNoNaturalCycle } from '../../core/runtime/revive-all.js';
11
5
  import { isParked } from '../../core/runtime/lifecycle.js';
12
- import { reviveNode } from '../../core/runtime/revive.js';
13
- import { isBrokerLive } from '../../core/runtime/model-swap.js';
14
- import { spawnChild } from '../../core/runtime/spawn.js';
15
6
  import { cronWakeOrigin } from '../../core/runtime/bearings.js';
16
- import { parseCronSink } from '../../core/canvas/crons.js';
17
7
  import { resolveLiveProfile, resolveLiveProfileName } from './armed-context.js';
18
- async function deliverNodeSink(c, target, stdout) {
19
- const meta = getNode(target);
20
- if (meta === null)
21
- throw new Error(`node sink ${target} is gone`);
22
- // A cron is an explicit next cycle for a clock-parked node, not other done nodes.
23
- if (hasNoNaturalCycle(meta) && !isParked(meta)) {
24
- throw new Error(`node sink ${target} has no natural cycle ahead (done or finalized)`);
25
- }
26
- const from = c.created_by != null && getNode(c.created_by) !== null ? c.created_by : null;
27
- const entry = appendInbox(target, {
28
- from,
29
- tier: c.tier,
30
- kind: 'message',
31
- label: `⏰ cron ${c.name}`,
32
- data: { body: stdout },
33
- });
34
- if (entry.tier !== 'deferred' || meta.frozen_at !== null)
35
- cancelCronsOnWake(target);
36
- // The APPENDED tier decides the wake, not the cron's requested one: a deferred
37
- // cron aimed at a terminal node was raised out of `deferred` by the append.
38
- // The durable append succeeds even if its best-effort wake fails.
39
- if (entry.tier !== 'deferred' && !isBrokerLive(meta)) {
40
- try {
41
- await reviveNode(target, { resume: true, capacity: 'freeze' });
42
- }
43
- catch {
44
- /* best-effort wake — the entry is durably appended regardless */
45
- }
46
- }
47
- }
48
- async function deliverSpawnSink(c, kind, stdout) {
49
- const creatorAlive = c.created_by != null && getNode(c.created_by) !== null;
50
- const prompt = [
51
- `Scheduled cron "${c.name}" (${c.cron_id}) fired and delivered its output to you as your kickoff.`,
52
- '',
53
- '## Command output',
54
- '',
55
- stdout,
56
- ].join('\n');
57
- const res = await spawnChild({
58
- kind,
59
- cwd: c.cwd,
60
- prompt,
61
- // Creatorless sinks are terminal roots so each run reaps without stealing focus.
62
- ...(creatorAlive ? { parent: c.created_by } : { root: true, rootLifecycle: 'terminal' }),
63
- readiness: 'launch',
64
- profile: resolveLiveProfile(c),
65
- wakeOrigin: cronWakeOrigin(c, 'node_birth'),
66
- });
67
- return res.node.node_id;
68
- }
69
- function deliverHumanSink(c, stdout) {
70
- const synthesized = writeSynthesizedPage(synthesizedPageDocument(`⏰ cron ${c.name}`, `Scheduled cron "${c.name}" delivered output for your attention.`, stdout, false));
71
- // Validate verbatim stdout before minting a ticket to avoid a half-built page.
72
- let prepared;
73
- try {
74
- const profileName = resolveLiveProfileName(c);
75
- prepared = preparePage({
76
- sourceFile: synthesized.path,
77
- source: {
78
- sessionName: `cron ${c.name} (${c.cron_id})`,
79
- ...(profileName === undefined ? {} : { profileName }),
80
- },
81
- productKinds: resolvePageComponents(),
82
- delivery: { placement: 'inline', inbox: true, reply: false },
83
- });
84
- }
85
- finally {
86
- rmSync(synthesized.dir, { recursive: true, force: true });
87
- }
88
- const id = `page-${randomBytes(4).toString('hex')}`;
89
- publishPage(ticketDir(id), prepared);
90
- }
91
- export async function deliverToSink(c, stdout) {
8
+ /** Resolve a completed run into a durable obligation. No sink effect happens here. */
9
+ export function resolveCronSink(c, runId, stdout) {
92
10
  const sink = parseCronSink(c.sink);
93
11
  if (sink === null)
94
- return 'no sink armed — nothing delivered';
12
+ return { kind: 'none', delivered: 'no sink armed — nothing delivered' };
95
13
  if (sink.kind === 'node') {
96
- await deliverNodeSink(c, sink.node, stdout);
97
- return `delivered: node ${sink.node}`;
14
+ const meta = getNode(sink.node);
15
+ if (meta === null)
16
+ throw new Error(`node sink ${sink.node} is gone`);
17
+ if (hasNoNaturalCycle(meta) && !isParked(meta)) {
18
+ throw new Error(`node sink ${sink.node} has no natural cycle ahead (done or finalized)`);
19
+ }
20
+ return {
21
+ kind: 'node',
22
+ destinationNodeId: sink.node,
23
+ senderNodeId: c.created_by !== null && getNode(c.created_by) !== null ? c.created_by : null,
24
+ label: `⏰ cron ${c.name}`,
25
+ stdout,
26
+ urgency: c.tier,
27
+ };
98
28
  }
99
29
  if (sink.kind === 'spawn') {
100
- const nodeId = await deliverSpawnSink(c, sink.spawn, stdout);
101
- return `delivered: spawned ${nodeId}`;
30
+ const creatorAlive = c.created_by !== null && getNode(c.created_by) !== null;
31
+ const prompt = [
32
+ `Scheduled cron "${c.name}" (${c.cron_id}) fired and delivered its output to you as your kickoff.`,
33
+ '',
34
+ '## Command output',
35
+ '',
36
+ stdout,
37
+ ].join('\n');
38
+ return {
39
+ kind: 'external',
40
+ destinationId: 'cron_spawn',
41
+ adapter: {
42
+ adapter: 'cron_spawn', cronId: c.cron_id, nodeId: newNodeId(), kind: sink.spawn, cwd: c.cwd,
43
+ ...(creatorAlive ? { parent: c.created_by, root: false } : { parent: null, root: true, rootLifecycle: 'terminal' }),
44
+ profile: resolveLiveProfile(c), wakeOrigin: cronWakeOrigin(c, 'node_birth'), prompt,
45
+ },
46
+ bodyJson: { runId, stdout },
47
+ };
102
48
  }
103
- deliverHumanSink(c, stdout);
104
- return 'delivered: human send --inbox';
49
+ return {
50
+ kind: 'external',
51
+ destinationId: 'cron_human',
52
+ adapter: {
53
+ adapter: 'cron_human', cronId: c.cron_id, requestId: newNodeId(), title: `⏰ cron ${c.name}`,
54
+ summary: `Scheduled cron "${c.name}" delivered output for your attention.`, sessionName: `cron ${c.name} (${c.cron_id})`,
55
+ profileName: resolveLiveProfileName(c) ?? null,
56
+ },
57
+ bodyJson: { runId, stdout },
58
+ };
105
59
  }
@@ -3,8 +3,6 @@
3
3
  // raw fatal boundary; a winning daemon stays alive through its scheduled loop.
4
4
  import '../suppress-experimental-warnings.js';
5
5
  import { runDaemon } from './crtrd.js';
6
- import { DAEMON_EXIT_STARTUP_BLOCKED } from './startup-policy.js';
7
- import { blockedMigrationIn, recordDaemonStartupBlocked } from './startup-block-marker.js';
8
6
  import { envCrtrdTcp } from '../shared/env.js';
9
7
  /** Extract `--tcp <host:port>` (or `--tcp=<host:port>`) from argv; falls back to
10
8
  * `CRTRD_TCP`. Absent → unix socket only (§4.1). */
@@ -18,21 +16,8 @@ function parseTcpArg(argv) {
18
16
  }
19
17
  return envCrtrdTcp();
20
18
  }
21
- // A blocked migration is the one startup failure guaranteed to recur, so it
22
- // exits on its own code rather than reaching Node's raw fatal boundary like
23
- // every other failure.
24
- try {
25
- await runDaemon({ tcp: parseTcpArg(process.argv.slice(2)) });
26
- }
27
- catch (error) {
28
- // Record it in the canvas home BEFORE exiting: the exit code alone only
29
- // reaches the one process that spawned us, and the processes that would spawn
30
- // the next daemon are all different processes with no memory of this. The
31
- // marker is what makes the suppression outlive this pid.
32
- const blocked = blockedMigrationIn(error);
33
- if (blocked === null)
34
- throw error;
35
- recordDaemonStartupBlocked(blocked.message, blocked.blockerPaths);
36
- process.stderr.write(`[crtrd] startup blocked\n${blocked.message}\n`);
37
- process.exit(DAEMON_EXIT_STARTUP_BLOCKED);
19
+ function parsePrepareArg(argv) {
20
+ return argv.includes('--prepare');
38
21
  }
22
+ const argv = process.argv.slice(2);
23
+ await runDaemon({ tcp: parseTcpArg(argv), prepare: parsePrepareArg(argv) });
@@ -13,6 +13,8 @@ export interface DaemonOpts {
13
13
  /** Opt-in TCP listener for the API server as `host:port` (§4.1). Falls back
14
14
  * to `CRTRD_TCP` when unset. Absent → unix socket only. */
15
15
  tcp?: string;
16
+ /** Hold after storage preparation until `POST /v1/daemon/admit`. */
17
+ prepare?: boolean;
16
18
  }
17
19
  /** Start the supervisor loop after winning the authoritative canvas claim.
18
20
  *