@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
@@ -0,0 +1,68 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { openDb, withCanvasWrite } from './db.js';
3
+ import { capturePidIdentities, identitiesMatch, isBootScopedIdentity, isLegacyTicksIdentity } from './pid.js';
4
+ function now() {
5
+ return new Date().toISOString();
6
+ }
7
+ function hydrate(row) {
8
+ return {
9
+ executionId: row['execution_id'],
10
+ nodeId: row['node_id'],
11
+ daemonEpoch: row['daemon_epoch'] ?? null,
12
+ pid: row['pid'] ?? null,
13
+ processIdentity: row['process_identity'] ?? null,
14
+ state: row['state'],
15
+ startedAt: row['started_at'],
16
+ endedAt: row['ended_at'] ?? null,
17
+ exitReason: row['exit_reason'] ?? null,
18
+ };
19
+ }
20
+ export function liveExecutionForNode(nodeId) {
21
+ const row = openDb().prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(nodeId);
22
+ return row === undefined ? null : hydrate(row);
23
+ }
24
+ export function beginExecution(nodeId, input) {
25
+ return withCanvasWrite((db) => {
26
+ const at = now();
27
+ db.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(at, nodeId);
28
+ const executionId = randomUUID();
29
+ db.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL)").run(executionId, nodeId, input.daemonEpoch, at);
30
+ return executionId;
31
+ });
32
+ }
33
+ /** Returns shutdown when a late broker references an execution no longer live. */
34
+ export function recordExecutionPid(executionId, nodeId, pid) {
35
+ const identity = capturePidIdentities([pid])?.get(pid) ?? null;
36
+ return withCanvasWrite((db) => {
37
+ const launching = db.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running' WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(pid, identity, executionId, nodeId);
38
+ if (launching.changes > 0)
39
+ return 'recorded';
40
+ const running = db.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(executionId, nodeId);
41
+ return running?.pid === pid ? 'recorded' : 'shutdown';
42
+ });
43
+ }
44
+ export function endExecution(executionId, input) {
45
+ return Number(openDb().prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(now(), input.reason, executionId).changes) === 1;
46
+ }
47
+ export function abortExecution(executionId, input) {
48
+ return endExecution(executionId, input);
49
+ }
50
+ export function endLiveExecution(nodeId, input) {
51
+ return Number(openDb().prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(now(), input.reason, nodeId).changes) === 1;
52
+ }
53
+ export function migrateLegacyExecutionIdentities(captureIdentity = (pid) => capturePidIdentities([pid])?.get(pid)) {
54
+ const db = openDb();
55
+ const rows = db.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all();
56
+ const update = db.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'");
57
+ const migrated = [];
58
+ for (const row of rows) {
59
+ if (!isLegacyTicksIdentity(row.process_identity))
60
+ continue;
61
+ const current = captureIdentity(row.pid);
62
+ if (current === undefined || !isBootScopedIdentity(current) || !identitiesMatch(current, row.process_identity))
63
+ continue;
64
+ if (update.run(current, row.execution_id, row.pid, row.process_identity).changes > 0)
65
+ migrated.push(row.execution_id);
66
+ }
67
+ return { migrated };
68
+ }
@@ -4,16 +4,16 @@
4
4
  // there plus the artifacts it left — its `reports/` (append-only push history:
5
5
  // final/update/urgent outcome summaries) and `context/` docs (specs, designs,
6
6
  // roadmaps, findings). This module is the ONE place that scans that corpus; it
7
- // lives in the canvas data-access layer, so it resolves every node + path
8
- // through canvas.ts + paths.ts and never hand-joins. No persistent index —
9
- // node facets (cwd/kind/status) are filtered cheaply against the db FIRST, then
10
- // only the surviving nodes' artifact files are read. FTS5/bm25 is the future
11
- // upgrade; the surface above is backend-independent.
7
+ // lives in the canvas data-access layer, so it resolves every node and artifact
8
+ // path through canvas.ts + paths.ts. Node facets (cwd/kind/status) are filtered
9
+ // in SQL first, then only the surviving nodes' artifact files are read. FTS5/bm25
10
+ // is the future upgrade; the surface above is backend-independent.
12
11
  import { envNodeId } from '../../shared/env.js';
13
12
  import { statSync, readdirSync } from 'node:fs';
14
13
  import { join, relative, sep } from 'node:path';
15
14
  import { getNode, listNodes, view } from './canvas.js';
16
- import { contextDir, reportsDir, nodeDir, inboxPath, sessionPtrPath } from './paths.js';
15
+ import { contextDir, reportsDir, nodeDir } from './paths.js';
16
+ import { openDb } from './db.js';
17
17
  import { readTextIfExists, walkFiles, pathExists } from '../fs-utils.js';
18
18
  import { parseFrontmatterGeneric } from '../frontmatter.js';
19
19
  import { warn } from '../output.js';
@@ -149,17 +149,23 @@ function docArtifact(row, desc, abs) {
149
149
  loadBody: load,
150
150
  };
151
151
  }
152
- /** Every entry ever appended to a node's inbox.jsonl, oldest first, cursor-
153
- * independent (the cursor only gates the live wake path, not this read).
154
- * Empty when the node has no inbox file yet. */
152
+ /** Every active-inbox delivery ever recorded for a node, including canceled
153
+ * and acknowledged deliveries. Message sequence is the durable replacement
154
+ * for the old file's physical append order. */
155
155
  function allInboxEntries(nodeId) {
156
- const raw = readTextIfExists(inboxPath(nodeId));
157
- if (raw === null)
158
- return [];
159
- return raw
160
- .split('\n')
161
- .filter((l) => l.trim() !== '')
162
- .map((l) => JSON.parse(l));
156
+ const rows = openDb().prepare(`SELECT m.created_at, m.sender_node_id, d.urgency, m.kind, m.label, m.body_ref, m.body_json
157
+ FROM deliveries d JOIN messages m ON m.message_id = d.message_id
158
+ WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND d.wake = 1
159
+ ORDER BY m.seq, d.created_at, d.delivery_id`).all(nodeId);
160
+ return rows.map((row) => ({
161
+ ts: row.created_at,
162
+ from: row.sender_node_id,
163
+ tier: row.urgency,
164
+ kind: row.kind,
165
+ label: row.label,
166
+ ref: row.body_ref,
167
+ data: row.body_json === null ? null : JSON.parse(row.body_json),
168
+ }));
163
169
  }
164
170
  function reportBodyFromRef(ref) {
165
171
  try {
@@ -187,16 +193,19 @@ function reportBodyFromRef(ref) {
187
193
  function inboxEntryBody(e) {
188
194
  const meta = [`from: ${e.from ?? 'system'}`, `tier: ${e.tier}`].join('\n');
189
195
  const header = `[${e.kind}] ${e.label}`;
190
- const inlinePreview = typeof e.data?.['body'] === 'string' ? e.data['body'].trim() : '';
191
- const isSpilledMessage = typeof e.data?.['body'] === 'string';
192
- const full = e.ref !== undefined
196
+ const dataBody = typeof e.data === 'object' && e.data !== null && !Array.isArray(e.data)
197
+ ? e.data['body']
198
+ : undefined;
199
+ const inlinePreview = typeof dataBody === 'string' ? dataBody.trim() : '';
200
+ const isSpilledMessage = typeof dataBody === 'string';
201
+ const full = e.ref !== null
193
202
  ? isSpilledMessage
194
203
  ? (readTextIfExists(e.ref) ?? '')
195
204
  : reportBodyFromRef(e.ref) ?? fileBodyLoader(e.ref).load()
196
205
  : inlinePreview;
197
206
  const hasBody = full !== '' && full !== e.label;
198
207
  const parts = [meta, header];
199
- if (e.ref !== undefined)
208
+ if (e.ref !== null)
200
209
  parts.push(`ref: ${e.ref}`);
201
210
  if (hasBody)
202
211
  parts.push(full);
@@ -229,21 +238,12 @@ function inboxArtifact(row, desc, entry, index) {
229
238
  a.from = entry.from;
230
239
  return a;
231
240
  }
232
- /** The node's session `.jsonl`, or null when nothing has been written yet. pi
233
- * binds the path at session creation but writes the file on the FIRST appended
234
- * entry, so a fresh node has a bound path that is not yet on disk. Mirrors
235
- * `runtime/node-read.ts`'s resolution: the recorded path first, then the
236
- * `session.ptr` the node dir carries. */
241
+ /** The node's SQL-recorded session `.jsonl`, or null when nothing has been
242
+ * written yet. Pi binds the path at session creation but writes the file on the
243
+ * first appended entry, so a fresh node may have a path that is not on disk. */
237
244
  function resolveSessionFile(nodeId) {
238
- const node = getNode(nodeId);
239
- const recorded = node?.pi_session_file;
240
- if (typeof recorded === 'string' && recorded !== '' && pathExists(recorded))
241
- return recorded;
242
- const raw = readTextIfExists(sessionPtrPath(nodeId));
243
- if (raw === null)
244
- return null;
245
- const target = raw.trim();
246
- return target !== '' && pathExists(target) ? target : null;
245
+ const recorded = getNode(nodeId)?.pi_session_file;
246
+ return typeof recorded === 'string' && recorded !== '' && pathExists(recorded) ? recorded : null;
247
247
  }
248
248
  /** The searchable text of a message's content blocks. `thinking` blocks are
249
249
  * deliberately dropped: private model reasoning is excluded from every human
@@ -478,7 +478,7 @@ function warnInvalidFrontmatter(path, error) {
478
478
  const message = (error instanceof Error ? error.message : String(error)).split('\n')[0];
479
479
  warn(`invalid frontmatter in ${path}: ${message}`);
480
480
  }
481
- /** The node desc lives in meta.json, not the row — read it once per survivor. */
481
+ /** Read a node description once for each surviving SQL row. */
482
482
  function nodeDescOf(nodeId) {
483
483
  const n = getNode(nodeId);
484
484
  return n?.description ?? '';
@@ -2,10 +2,12 @@ export * from './types.js';
2
2
  export * from './labels.js';
3
3
  export * from './paths.js';
4
4
  export * from './canvas.js';
5
+ export * from './executions.js';
6
+ export * from './sessions.js';
7
+ export * from './worktrees.js';
5
8
  export * from './source.js';
6
9
  export * from './history.js';
7
10
  export * from './focuses.js';
8
11
  export * from './crons.js';
9
- export * from './node-outcome-deliveries.js';
10
12
  export * from './telemetry.js';
11
13
  export { openDb, closeDb } from './db.js';
@@ -4,10 +4,12 @@ export * from './types.js';
4
4
  export * from './labels.js';
5
5
  export * from './paths.js';
6
6
  export * from './canvas.js';
7
+ export * from './executions.js';
8
+ export * from './sessions.js';
9
+ export * from './worktrees.js';
7
10
  export * from './source.js';
8
11
  export * from './history.js';
9
12
  export * from './focuses.js';
10
13
  export * from './crons.js';
11
- export * from './node-outcome-deliveries.js';
12
14
  export * from './telemetry.js';
13
15
  export { openDb, closeDb } from './db.js';
@@ -3,7 +3,7 @@
3
3
  // `PRAGMA user_version`: schema DDL, one-time data backfills, and the
4
4
  // journaled on-disk-lane splice (`../../migrations/registry.ts`'s
5
5
  // `journaled` entries, appended at the tail of `MIGRATIONS`). A step here
6
- // runs inside `db.ts`'s per-open `migrate()`, exactly once per database,
6
+ // runs through the daemon's explicit `migrate()` startup call, exactly once per database,
7
7
  // transactionally.
8
8
  //
9
9
  // The other two homes:
@@ -21,6 +21,10 @@
21
21
  // `db.ts` itself keeps only connection management (`openDb`/`withCanvasWrite`
22
22
  // /`closeDb`) and re-exports `migrate`/`MIGRATIONS` from here so external
23
23
  // imports are unaffected by this split.
24
+ import { importNodeSqlAuthority } from './node-sql-migration.js';
25
+ import { migrateRecoveryWitnesses } from './recovery.js';
26
+ import { migrateMessagingState } from './deliveries.js';
27
+ import { migrateHumanRequestsState } from '../human/requests.js';
24
28
  import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
25
29
  import { basename, join, resolve } from 'node:path';
26
30
  import { crtrHome, isSafeNodeId, nodesRoot, nodeMetaPath } from './paths.js';
@@ -730,9 +734,8 @@ function reapRunningPredicateEvaluations(db) {
730
734
  /** v22 — migrate each scheduled action into a shell cron, preserving its id and
731
735
  * execution context, then remove the superseded table.
732
736
  *
733
- * SKIP-AND-RECORD, never throw. `migrate()` runs on every `openDb()`, so a
734
- * migration that hard-fails on data shape would make EVERY crtr process fail to
735
- * open the canvas forever. Rows the retired schema declared legal but this step
737
+ * SKIP-AND-RECORD, never throw. A migration that hard-fails on data shape would
738
+ * block daemon startup. Rows the retired schema declared legal but this step
736
739
  * cannot express (unknown action/timing pairs, a missing fire time, drifted
737
740
  * JSON) are skipped, named in the `canvas_meta` ledger under
738
741
  * `migration.v22.skipped`, and warned about — the schema always advances.
@@ -974,11 +977,7 @@ CREATE INDEX IF NOT EXISTS idx_warm_pool_recipe ON warm_pool(recipe_key, created
974
977
  * crtrd re-verify that a Visual event arrived through crouter's own
975
978
  * registered handler argv — that registry is deleted in this landing, so
976
979
  * there is nothing left to bind. `dir`/`root` collapse into `ticket_node_id`,
977
- * the bridge node id a ticket's directory is derived from at every call site
978
- * (`ticketDir(nodeId)` in `src/core/human/root.ts`) — `basename(dir)` IS that
979
- * node id today, already relied on as such at
980
- * `src/daemon/api/handlers/human.ts:290` (`const jobId = basename(dir)`) and
981
- * `src/core/canvas/attention.ts:21`.
980
+ * the bridge node id stored as `basename(dir)` in the input rows.
982
981
  *
983
982
  * THIS IS A TABLE REBUILD, NOT `ALTER TABLE … DROP COLUMN`: six of the nine
984
983
  * existing indexes are on `dir` (`idx_consult_outbox_dir`,
@@ -1459,6 +1458,12 @@ export const MIGRATIONS = [
1459
1458
  /* v38 */ addNodeLabelColumns,
1460
1459
  /* v39 */ addNodeOutcomeAndDeadline,
1461
1460
  ...JOURNALED_STATE_MIGRATIONS,
1461
+ (db) => {
1462
+ importNodeSqlAuthority(db);
1463
+ migrateRecoveryWitnesses(db);
1464
+ migrateMessagingState(db);
1465
+ migrateHumanRequestsState(db);
1466
+ },
1462
1467
  ];
1463
1468
  /** Migration indexes that manage their OWN transaction and therefore must not
1464
1469
  * be wrapped by `migrate()` — `node:sqlite` rejects a nested BEGIN. Index 3
@@ -1467,8 +1472,7 @@ export const MIGRATIONS = [
1467
1472
  * documents its own crash-safety: a partial rebuild rolls back and a re-run
1468
1473
  * over an already-rebuilt table is idempotent. (Entering `migrate()` from
1469
1474
  * INSIDE a caller's transaction with `user_version` still at 3 would make that
1470
- * internal BEGIN nest and throw — pre-existing and unreachable from `openDb()`,
1471
- * which migrates in autocommit.) */
1475
+ * internal BEGIN nest and throw; daemon startup calls it in autocommit.) */
1472
1476
  const SELF_TRANSACTIONAL_MIGRATIONS = new Set([3]);
1473
1477
  function currentUserVersion(db) {
1474
1478
  return db.prepare('PRAGMA user_version').get().user_version;
@@ -1492,7 +1496,11 @@ function applyMigration(db, v) {
1492
1496
  * acquiring it so a step another process just applied is skipped rather than
1493
1497
  * re-run. */
1494
1498
  export function migrate(db) {
1495
- if (currentUserVersion(db) >= MIGRATIONS.length)
1499
+ const version = currentUserVersion(db);
1500
+ if (version > MIGRATIONS.length) {
1501
+ throw new Error(`unsupported canvas schema version ${version} (latest supported ${MIGRATIONS.length})`);
1502
+ }
1503
+ if (version === MIGRATIONS.length)
1496
1504
  return;
1497
1505
  // Pending work: a step now holds the write lock for its whole duration, and
1498
1506
  // the fs-heavy legacy steps (v3/v14/v15) can outlast the ordinary 5s busy
@@ -11,8 +11,6 @@
11
11
  // `FoldState`) so this layer owns no singletons and each consumer keeps its own
12
12
  // state.
13
13
  import { getNode, subscribersOf, subscriptionsOf } from './index.js';
14
- import { activeFaultForDisplay } from './render-source.js';
15
- import { readFault } from '../runtime/fault.js';
16
14
  import { faultSummary } from './status-glyph.js';
17
15
  import { statusRank } from './node-order.js';
18
16
  import { nodeGlyph, navLabel, shortId, tokensCell, activityCell, cycleBadge, askBadge, liveBelowBadge, truncate, fillBar, fillWidth, isAttached, BOLD, DIM, RESET, REVERSE, BG_ATTACHED, } from './nav-render.js';
@@ -226,7 +224,7 @@ export function renderGraphRow(r, isCursor, focused, activeBelow, asks) {
226
224
  // reads purely as "this unfolds".
227
225
  const expandable = r.hasKids && r.collapsed;
228
226
  const caret = !isCursor && expandable ? `${DIM}▸${RESET} ` : ' ';
229
- const fault = node !== null ? activeFaultForDisplay(node, readFault(r.id)) : null;
227
+ const fault = node?.fault ?? null;
230
228
  const faultSuffix = fault !== null ? ` · ${faultSummary(fault)}` : '';
231
229
  const line = `${r.branch}${caret}${dot} ${name} ${kind} ${tokens}${cycleBadge(node)}${childBadge(node)}${liveBelowBadge(node, activeBelow)}${askBadge(r.id, asks)}${activityCell(r.id, node)}${faultSuffix}`;
232
230
  return wrap(line, isAttached(r.id, node, focused));
@@ -19,10 +19,10 @@ export declare const YELLOW = "\u001B[33m";
19
19
  export declare const CYAN = "\u001B[36m";
20
20
  export declare const GRAY = "\u001B[90m";
21
21
  /** Overlay-aware glyph for a node: hanging ⚠ outranks streaming ⟳, which
22
- * outranks the base status glyph. `remote` skips the local `readFault` /
23
- * `isPidAlive` / `isBusy` reads entirely (a remote node id may collide with a
24
- * local one) and renders the bare status glyph instead. */
25
- export declare function nodeGlyph(node: NodeMeta | null, remote?: boolean): string;
22
+ * outranks the base status glyph. Every input is a projected row field — the
23
+ * owning daemon computed `fault`/`streaming` — so this holds for a remote node
24
+ * too, with no local read keyed on a node id that may collide. */
25
+ export declare function nodeGlyph(node: NodeMeta | null): string;
26
26
  /** Drop every SGR sequence, keeping the visible text. The selection bar uses
27
27
  * this: reverse-video INVERTS a coloured cell into a coloured block, so a row
28
28
  * built from tinted spans highlights as a patchwork of background swatches
@@ -1,8 +1,8 @@
1
1
  // nav-render.ts — the PURE render + telemetry half of the nav model.
2
2
  //
3
3
  // Everything here is canvas-db-free: it reads node telemetry (job/telemetry.json,
4
- // attach.json — pure `jobDir` fs reads), per-node fault/busy/pid marker files, and
5
- // produces ANSI-styled strings. No `getNode`/`subscriptionsOf`/`listFocuses` — the
4
+ // attach.json — pure `jobDir` fs reads) plus the fault/streaming fields already
5
+ // projected onto the node row, and produces ANSI-styled strings. No `getNode`/`subscriptionsOf`/`listFocuses` — the
6
6
  // graph-walking half lives in nav-model.ts (which re-exports these helpers for its
7
7
  // own callers). This split lets the attach viewer's pure chrome pull render helpers
8
8
  // without dragging the canvas state-store into its bundle.
@@ -10,10 +10,6 @@ import { execFileSync } from 'node:child_process';
10
10
  import { existsSync, readFileSync } from 'node:fs';
11
11
  import { join } from 'node:path';
12
12
  import { jobDir } from './paths.js';
13
- import { isPidAlive } from './pid.js';
14
- import { isBusy } from '../runtime/busy.js';
15
- import { readFault } from '../runtime/fault.js';
16
- import { activeFaultForDisplay } from './render-source.js';
17
13
  import { isFrozenRow, resolveNodeVisual } from './status-glyph.js';
18
14
  // Tuning constants
19
15
  /** pi's InteractiveMode.MAX_WIDGET_LINES — the hard cap on lines in a string
@@ -41,30 +37,24 @@ export const RED = `${ESC}31m`;
41
37
  export const YELLOW = `${ESC}33m`;
42
38
  export const CYAN = `${ESC}36m`;
43
39
  export const GRAY = `${ESC}90m`;
44
- function hangingFor(node) {
45
- return activeFaultForDisplay(node, readFault(node.node_id));
46
- }
47
40
  function streamingFor(node) {
48
41
  if (node.status !== 'active' && node.status !== 'idle')
49
42
  return false;
50
- if (!isPidAlive(node.pi_pid))
51
- return false;
52
- // `isBusy` (the canonical mid-turn marker) AND-ed with the live pid above —
53
- // a stale marker from a crashed pi fails the pid check, never the existsSync.
54
- return isBusy(node.node_id);
43
+ // The projected field is the live execution's open turn AND-ed with broker-pid
44
+ // liveness, so a witness left by a crashed pi reads false.
45
+ return node.streaming === true;
55
46
  }
56
47
  /** Overlay-aware glyph for a node: hanging ⚠ outranks streaming ⟳, which
57
- * outranks the base status glyph. `remote` skips the local `readFault` /
58
- * `isPidAlive` / `isBusy` reads entirely (a remote node id may collide with a
59
- * local one) and renders the bare status glyph instead. */
60
- export function nodeGlyph(node, remote = false) {
48
+ * outranks the base status glyph. Every input is a projected row field — the
49
+ * owning daemon computed `fault`/`streaming` — so this holds for a remote node
50
+ * too, with no local read keyed on a node id that may collide. */
51
+ export function nodeGlyph(node) {
61
52
  if (node === null)
62
53
  return '?';
63
54
  const v = resolveNodeVisual(node.status, {
64
- streaming: remote ? false : streamingFor(node),
65
- // Durable row state, so it holds for a remote node too.
55
+ streaming: streamingFor(node),
66
56
  frozen: isFrozenRow(node),
67
- hanging: remote ? null : hangingFor(node),
57
+ hanging: node.fault ?? null,
68
58
  });
69
59
  return `${ESC}${v.color}m${v.glyph}${RESET}`;
70
60
  }
@@ -0,0 +1,3 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ /** Imported by the shared appended consolidation transaction. The caller owns the transaction and user_version. */
3
+ export declare function importNodeSqlAuthority(db: DatabaseSync): void;